等待 pthread_create 完成而不使用 pthread_join
Posted
技术标签:
【中文标题】等待 pthread_create 完成而不使用 pthread_join【英文标题】:Waiting for pthread_create to finish without using pthread_join 【发布时间】:2009-04-08 12:25:11 【问题描述】:我想暂停一个线程,直到另一个线程完成初始化而不使用 pthread_join。 我尝试使用连接,但由于我们拥有一些异步线程间通信系统,它会导致死锁。 现在,我正在使用(自定义)锁来实现这一点。
在线程 1 中:
lock_OfflineWorker.Lock()
if (pthread_create(&tid0, NULL, RunOfflineWorker, NULL) != 0)
lock_OfflineWorker.TryLock();
lock_OfflineWorker.Unlock();
在线程 2 中:
bool OfflineWorker::Initialize()
lock_OfflineWorker.Unlock();
但这很不雅,我不太确定副作用(可能会再次陷入僵局)。 这个可以吗? 如果没有,是否有另一种方法来实现这一点(使用锁或其他方式)
编辑:忘记包含“RunOfflineWorker”功能
void* RunOfflineWorker(void* pData)
g_OfflineWorker.Initialize();
【问题讨论】:
OfflineWorker 进行初始化,然后继续进行其他一些工作,对吗? 是的。在实际函数的底部有一个返回。它执行一些心跳操作(库函数),但不执行任何繁重的操作 您不能(可移植地)从您锁定它的不同线程解锁 pthread 互斥锁。见opengroup.org/onlinepubs/007908775/xsh/pthread_mutex_lock.html。使用如下建议的条件变量。 @Doug:是的,但是你可以用 POSIX 信号量做同样的事情。我建议不要在这里使用条件变量;事实是发。仅在两次编辑不言自明后,才成功地做到了。 【参考方案1】:您可以使用 pthread 条件等待作业达到所需状态。
thread1 用pthread_cond_wait()
等待,thread2 用pthread_cond_signal()
发出信号。
你需要:
bool condition ; // or anything else to be tested
pthread_mutex_t mutex ;
pthread_cond_t cond ;
第一个线程初始化:
condition = false ;
pthread_mutex_init( &mutex , PTHREAD_MUTEX_INITIALIZER );
pthread_cond_init( &cond , PTHREAD_COND_INITIALIZER );
然后它在互斥锁锁定的情况下等待。 通常你把等待放在一个循环中来检查条件是什么。
pthread_mutex_lock( &mutex );
while( ! condition )
pthread_cond_wait( &cond , &mutex );
pthread_mutex_unlock( &mutex );
其他线程在适当的时候这样做:
pthread_mutex_lock( &mutex );
condition = true ; // or false ...
pthread_cond_signal( &cond );
pthread_mutex_unlock( &mutex );
【讨论】:
我让系统使用 pthread 条件工作。我没有使用while循环,只是在条件上调用了wait。我应该在调用 pthread_cond_wait 之前锁定互斥锁吗? pthread_cond_wait 不会自动锁定和解锁给定的互斥锁吗? 好的,我添加了init。循环用于检查条件是否真正满足,因为线程 2 也可以使用 : condition = false ; pthread_cond_signal(cond);是的,您必须先锁定它,因为 pthread_cond_wait 会解锁它。 必须锁定互斥体才能使用条件变量。如果您只想等到线程初始化,那么 (1) 互斥锁应该在condition = true
之前锁定并在之后解锁,以及 (2) 在 while (!condition)
之前锁定并在循环之后解锁。
现在可以正常使用了。感谢等待 OL 线程 // 线程 1 线程已注册 // 线程 2 获取 OL 锁 // 线程 2 ... 服务器已创建 : ... 释放 OL 锁 // 线程 2 线程已创建 [OfflineWorker] // 线程 1
如果 pthread_cond_signal 在初始化线程调用 pthread_cond_wait 之前被新线程调用怎么办?【参考方案2】:
我认为您的解决方案很好,除了您需要在线程 1 中使用 lock_OfflineWorker.Lock()
而不是 lock_OfflineWorker.TryLock()
- 使用 TryLock()
,它实际上不会等待任何东西。您不能为此使用互斥锁,因为它需要由锁定它的同一线程释放,但是例如。基于信号量的锁就可以了。使用监视器(即 mutex+condvar)会更复杂。
关于死锁:如果 OfflineWorker 的初始化部分(即释放锁之前的代码)不在任何地方等待,则死锁是不可能的。如果您的解决方案存在实际死锁,则任何其他使线程 1 等待线程 2 的解决方案也会有它们(我可以想象这种情况)。
注释后编辑:如果在线程 1 等待线程 2 的初始化完成时将消息传递给它,则可能会出现死锁,特别是如果消息有一些有界缓冲区或消息传递函数等待时回复。在这种情况下,我建议放弃等待线程 2 的想法,并可能在初始化完成时传递一些将从线程 2 调用的回调。
【讨论】:
我在这里对代码进行了很多缩写。那里有将消息传递给线程 1 的函数,但正如您所说,这些不应导致任何死锁。我会调查的。谢谢以上是关于等待 pthread_create 完成而不使用 pthread_join的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中运行另一个脚本而不等待它完成? [复制]