我想暂停一个线程,直到另一个线程完成初始化而不使用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();
}
答案 0 :(得分:7)
您可以使用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 );
答案 1 :(得分:1)
我认为您的解决方案很好,除了您需要在线程1中使用lock_OfflineWorker.Lock()
而不是lock_OfflineWorker.TryLock()
- 使用TryLock()
,它实际上并不等待任何事情。你不能使用互斥锁,因为它需要被锁定它的同一个线程释放,但是例如。一个基于信号量的锁会做。使用监视器(即mutex + condvar)会更复杂。
关于死锁:如果OfflineWorker的初始化部分(即释放锁之前的代码)不在任何地方等待,则死锁是不可能的。如果你的解决方案存在实际的死锁,那么让线程1等待线程2的任何其他解决方案都会有它们(我可以想象这种情况)。
注释后编辑:如果在等待线程2的初始化完成时将消息传递给线程1,则可能会出现死锁,特别是如果消息存在某些有界缓冲区或消息传递函数等待回复。在这种情况下,我建议放弃等待线程2的想法,并可能传递一些在初始化完成时从线程2调用的回调。