代码之家  ›  专栏  ›  技术社区  ›  Gayan

等待pthread_create完成而不使用pthread_join

  •  1
  • Gayan  · 技术社区  · 15 年前

    我想停止一个线程,直到另一个线程完成初始化,而不使用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();
    }
    
    2 回复  |  直到 15 年前
        1
  •  7
  •   fa.    15 年前

    可以使用pthread条件等待作业达到所需状态。

    thread1将与其他线程一起等待 pthread_cond_wait() 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 );
    
        2
  •  1
  •   jpalecek    15 年前

    我认为你的解决方案很好,只是你需要使用 lock_OfflineWorker.Lock() 而不是 lock_OfflineWorker.TryLock() 在线程1中-使用 TryLock() 实际上,它并不等待任何事情。不能使用互斥锁,因为它需要由锁定它的同一个线程释放,但是基于信号量的锁就可以了。使用监视器(即互斥+condvar)会更加复杂。

    关于死锁:如果OfflineWorker的初始化部分(即释放锁之前的代码)没有在任何地方等待,死锁是不可能的。如果您的解决方案中存在实际的死锁,那么让线程1等待线程2的任何其他解决方案也会有死锁(我可以想象这种情况)。

    注释后编辑:如果在线程1等待线程2的初始化完成时将消息传递给线程1,则可能会出现死锁,特别是当消息存在某个有界缓冲区或消息传递函数等待回复时。在这种情况下,我建议放弃等待线程2的想法,并可能传递一些回调,当初始化完成时,将从线程2调用这些回调。