即使主线程已终止,也保持线程处于活动状态

时间:2014-03-16 15:31:12

标签: multithreading c++11

我不确定我的问题是否正确,但我有以下示例,其中主线程创建了两个额外的线程。 由于我没有在main的末尾使用join命令,它将继续执行,同时,两个创建的线程将并行工作。但由于主要在完成执行之前终止,我得到以下输出:

在没有活动异常的情况下终止调用

已中止(核心转储)

以下是代码:

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <chrono>

void foo()
{
    std::chrono::milliseconds dura( 2000 );
    std::this_thread::sleep_for( dura );
    std::cout << "Waited for 2Sec\n";
}

void bar(int x)
{
    std::chrono::milliseconds dura( 4000 );
    std::this_thread::sleep_for( dura );
    std::cout << "Waited for 4Sec\n";
}

int main()
{
  std::thread first (foo);
  std::thread second (bar,0);

  return 0;
}

所以我的问题是如果主线程终止,如何保持这两个线程的工作?

我问这个是因为在我的主程序中,我有一个事件处理程序,并为每个事件创建一个相应的线程。但是当处理程序创建新线程时,主要问题是处理程序将继续执行。直到它被销毁,这也将导致新创建的线程被销毁。所以我的问题是如何在这种情况下保持线程活着?

此外,如果我使用连接,它将转换回序列化。

 void ho_commit_indication_handler(message &msg, const boost::system::error_code &ec)
 {
     .....
 }

 void event_handler(message &msg, const boost::system::error_code &ec)
{
   if (ec)
   {
    log_(0, __FUNCTION__, " error: ", ec.message());
    return;
   }

switch (msg.mid())
{
    case n2n_ho_commit:
    {
        boost::thread thrd(&ho_commit_indication_handler, boost::ref(msg), boost::ref(ec));
    }
    break
}
};

非常感谢。

1 个答案:

答案 0 :(得分:0)

保持线程活着是一个坏主意,因为它会调用std::terminate。你应该明确地join线程:

int main()
{
  std::thread first (foo);
  std::thread second (bar, 0);
  first.join();
  second.join();
}

另一种方法是detach线程。但是,您仍然需要断言主线程的寿命更长(例如使用互斥锁/ condition_variable)。

这个C ++ 11标准的摘录与此相关:

  

15.5.1 std::terminate()函数[except.terminate]

     

1 在某些情况下,必须放弃异常处理以获得不那么微妙的错误   处理技术。 [注意:这些情况是:

     

[...]

     

- 在一个上调用析构函数或复制赋值运算符时   引用可连接线程的类型std::thread的对象

因此,在范围退出之前,您必须在线程上调用joindetach


关于你的编辑:你必须将线程存储在一个列表(或类似的)中,并在main完成之前等待它们中的每一个。更好的想法是使用线程池(因为这限制了创建的线程总数)。