简体   繁体   English

多线程程序线程连接问题

[英]Multithreaded program thread join issues

I am currently writing a multithreaded program where a thread may sometimes be created depending on certain circumstances. 我目前正在编写一个多线程程序,根据某些情况,有时可能会创建一个线程。 If this thread is created it needs to run independently of all other threads and I cannot afford to block any other threads to wait for it to join. 如果创建了这个线程,它需要独立于所有其他线程运行,我不能阻止任何其他线程等待它加入。 The length of time the spawned thread runs for varies; 生成的线程运行的时间长度各不相同; sometimes it can take up to a few hours. 有时它可能需要几个小时。

I have tried spawning the thread and putting a join in the destructor of the class which works fine, however if the code within the spawned thread finishes a long time before the destructor is called (which will be around 99% of the time) I would like the thread to kill itself freeing all its resources etc. 我已经尝试生成线程并在类的析构函数中添加一个正常工作的连接,但是如果生成的线程中的代码在析构函数被调用之前很长时间(这将是99%的时间)我会像杀死自己的线程释放所有资源等。

I looked into using detach for this, but you can't rejoin a detached thread and on the off chance the destructor is called before this thread finishes then the spawned thread will not finish and could have disastrous consequences. 我考虑使用detach,但你不能重新加入一个分离的线程,并且在这个线程完成之前调用析构函数然后生成的线程将无法完成并且可能产生灾难性的后果。

Is there any possible solution that ensures the thread finishes before the class is destructed as well as allowing it to join as soon as the thread finishes its work? 是否有任何可能的解决方案可以确保线程在类被破坏之前完成,并且一旦线程完成其工作就允许它加入?

I am using boost/c++11 for threading. 我正在使用boost / c ++ 11进行线程化。 Any help at all would be greatly appreciated. 任何帮助都将非常感激。

Thanks 谢谢

The thread may detach itself, releasing its resources. 线程可以自行分离,释放其资源。 If the destructor sees that the thread is joinable, ie still running, let it join. 如果析构函数看到线程可以连接,即仍然在运行,那么让它加入。 If the thread reaches its end, self-detach. 如果线程到达终点,则自行分离。 Possible race condition: is_joinable() returns true in destructor - thread detaches itself - destructor joins and fails miserably. 可能的竞争条件:is_joinable()在析构函数中返回true - 线程分离自身 - 析构函数连接并失败。 So use a mutex guarding the thread's decease: 所以使用一个互斥锁来保护线程的死亡:

struct ThreadContainer
{
   std::mutex threadEndMutex;
   std::thread theThread;

   ThreadContainer()
     : theThread([=]()
       {
         /* do stuff */

         // if the mutex is locked, the destructor is just
         // about to join, so we let him.
         if (threadEndMutex.try_lock())
           theThread.detach();
       })
   {}

   ~ThreadContainer()
   {
     // if the mutex is locked, the thread is just about 
     // to detach itself, so no need to join.
     // if we got the mutex but the thread is not joinable, 
     // it has detached itself already.
     if (threadEndMutex.try_lock() && theThread.is_joinable())
       theThread.join();
   }
};

PS: you might not even need the call to is_joinable, because if the thread detached itself, it never unlocked the mutex and try_lock fails. PS:你可能甚至不需要调用is_joinable,因为如果线程自己分离,它永远不会解锁互斥锁并且try_lock失败。

PPS: instead of the mutex, you may use std::atomic_flag: PPS:您可以使用std :: atomic_flag代替互斥锁:

struct ThreadContainer
{
   std::atmoic_flag threadEnded;
   std::thread theThread;

   ThreadContainer()
     : threadEnded(ATOMIC_FLAG_INIT)
     , theThread([=]()
       {
         /* do stuff */

         if (!threadEnded.test_and_set())
           theThread.detach();
       })
   {}

   ~ThreadContainer()
   {
     if (!threadEnded.test_and_set())
       theThread.join();
   }
};

You could define pauses/steps in your "independent" thread algorithm, and at each step you look at a global variable that helps you decide to cancel calculation and auto destroy, or to continue the calculation in your thread. 您可以在“独立”线程算法中定义暂停/步骤,并在每个步骤中查看一个全局变量,该变量可帮助您决定取消计算并自动销毁,或继续计算您的线程。

If global variable is not sufficient, ie if a more precise granularity is needed you should define a functor object for your thread function, this functor having a method kill(). 如果全局变量不够,即如果需要更精确的粒度,则应为线程函数定义一个仿函数对象,该仿函数具有方法kill()。 You keep references of the functors after you have launched them as threads. 在将它们作为线程启动后,您将保留对仿函数的引用。 And when you call the MyThreadFunctor::kill() it's sets a boolean field and this field is checked at each steps of your calculation in the functor thread-function itself.. 当你调用MyThreadFunctor :: kill()时,它会设置一个布尔字段,并在functor线程函数本身的计算的每个步骤中检查此字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 多线程C ++程序未使用向量并行运行 <thread> 和.join() - Multithreaded C++ Program Not Running In Parallel Using vector<thread> and .join() 在多线程程序中使用exprtk - Using exprtk in a multithreaded program 在多线程程序中捕获标准输出 - Capture stdout in multithreaded program 稀疏矩阵的多线程程序 - Multithreaded Program for Sparse Matrices 多线程程序中的stackoverflow - stackoverflow in multithreaded program 为什么在线程中使用system()时,多线程C程序在Mac OS X上强制使用单个CPU? - Why is a multithreaded C program forced to a single CPU on Mac OS X when system() is used in a thread? 在使用boost的多线程c ++程序中,是否有任何方法可以获取指向当前线程的指针? - In a multithreaded c++ program using boost, is there any way to get a pointer to the current thread? 使用websocketpp库在多线程程序中为endpoint.listen()创建单独的增强线程 - Creating a separate boost thread for endpoint.listen() in a multithreaded program using websocketpp library 将控制台程序转换为 MFC 应用程序(线程问题)(Pleora SDK) - Converting a Console Program into an MFC app (Thread issues) (Pleora SDK) 为什么仅加入1个线程却有5个线程时程序正常工作 - Why program works correctly while join only 1 thread but there are 5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM