在c ++中退出两个带有三个线程的并发队列

时间:2012-05-09 08:14:58

标签: c++ multithreading boost concurrency queue

我在退出多线程,多排队的c ++程序时遇到了问题。该图显示了队列和线程结构。图表在这里:http://i.stack.imgur.com/JGhXs.png

简而言之,我有三个线程和两个并发队列。 second_handler(second_thread)从第一个队列弹出并推送到第二个队列。所有(似乎)工作正常,直到我想通过按键盘键退出程序。我收到这个错误:

在抛出'boost :: exception_detail :: clone_impl>'的实例后终止调用   what():boost :: lock_error 中止

这是我的代码:

int main() {
        startMultiThreading();
        cout <<"I"<<endl;
    }

startMultiThreading

void startMultiThreading() {
    boost::thread_group someVar_workers;
    boost::thread_group someOtherVar_workers;

    concurrent_queue<someVar* > someVar_queue(&someVar_workers);
    concurrent_queue<someOtherVar*> someOtherVar_queue(&someOtherVar_workers);

    boost::thread *first_thread = new boost::thread(first_handler, &someVar_queue);
    boost::thread *second_thread = new boost::thread(second_handler, &someVar_queue, &someOtherVar_queue);
    boost::thread *third_thread = new boost::thread(third_handler, &someOtherVar_queue);

    someVar_workers.add_thread(first_thread);
    someVar_workers.add_thread(second_thread);

    someOtherVar_workers.add_thread(second_thread);
    someOtherVar_workers.add_thread(third_thread);

    while (true) {
        if (thread_should_exit) {
            cout << "threads should be killed" << endl;
            while (!someVar_queue.empty()) {
                usleep(1000);
            }
            someVar_workers.remove_thread(second_thread);
            while (!someOtherVar_queue.empty()) {
                usleep(1000);
            }
            someOtherVar_queue.cancel();
            someVar_workers.join_all();
            someOtherVar_workers.remove_thread(second_thread);
            someOtherVar_workers.join_all();
            break;
        }
        usleep(10000);
    }
    cout << "H" << endl;
}

我想要的是完成两个队列然后正常终止的程序。我期望在程序终止之前看到“我”打印。这是输出:

    End of first_handler
    threads should be 
    second_handler is canceled
    End of second_handler
    H
terminate called after throwing an instance of 'concurrent_queue<someOtherVar*>::Canceled'
Aborted
    Press [Enter] to close the terminal ...

关闭线程和队列时我做错了什么?

谢谢

1 个答案:

答案 0 :(得分:2)

首先,请参阅KillianDS的评论 - 您的示例太长了。

另一件事是:永远不要直接调用析构函数!!

析构函数是特殊的东西,语言可以在变量范围的末尾调用它。如果你手动调用它,它将被第二次调用,很可能会导致未定义的行为。

Calling destructor manually