2012-05-09 31 views
2

我在退出多线程多队列C++程序时遇到问题。该图显示了队列和线程结构。该图是:http://i.stack.imgur.com/JGhXs.png用C++中的三个线程退出两个并发队列

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

终止叫做抛出的一个实例后 '的boost :: exception_detail :: clone_impl>' 什么()的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; 
} 

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

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 ... 

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

谢谢

+0

这是一个巨大的代码量,请其降低到更小的东西。另外:当你点击abort命令时,抛出异常异常是什么? – KillianDS

+0

感谢您的评论KillianDS。 – NeViXa

回答

2

首先,看到KillianDS评论 - 您的例子是太长。

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

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

Calling destructor manually

+0

感谢KillianDS和G. Martinek的回复。有关析构函数和异常的两个明智的教训。我没有成功获得主印刷品的cout。但它可能没有必要。 – NeViXa