2009-04-08 91 views
1

我想暫停一個線程直到另一個線程完成初始化而不使用pthread_join。 我嘗試使用一個連接,但由於我們有一些異步的線程間通信系統,導致死鎖。 現在,我正在使用(自定義)鎖來實現此目的。等待pthread_create完成而不使用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

OfflineWorker執行初始化,然後繼續執行其他一些工作,對嗎? – jpalecek 2009-04-08 12:32:35

+0

是的。實際功能的底部有一個返回。它執行一些心跳的操作(庫函數),但不執行任何繁重的操作。 – Gayan 2009-04-08 12:36:06

+0

您不能(可移植地)從其鎖定的其他線程中解鎖pthread互斥鎖。請參閱http://opengroup.org/onlinepubs/007908775/xsh/pthread_mutex_lock.html。如下所示使用條件變量。 – Doug 2009-04-08 13:01:39

回答

7

可以使用並行線程條件,以等待作業到達想要的狀態。

thread1等待pthread_cond_wait(),thread2用pthread_cond_signal()發信號給它。

您需要:

bool   condition ; // or anything else to be tested 
pthread_mutex_t mutex ; 
pthread_cond_t cond ; 

第一個線程inits所有:

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

我認爲您的解決方案是蠻好的,只是你需要使用lock_OfflineWorker.Lock(),而不是lock_OfflineWorker.TryLock()螺紋1 - 與TryLock(),但實際上其不會別等任何東西。你不能使用互斥鎖,因爲它需要被鎖定它的同一個線程釋放,但是例如。一個基於信號量的鎖會做。使用監視器(即互斥鎖+ condvar)會更加複雜。

關於死鎖:如果OfflineWorker的初始化部分(即釋放鎖之前的代碼)不會在任何地方等待,死鎖是不可能的。如果你的解決方案存在實際的死鎖問題,那麼讓線程1等待線程2的任何其他解決方案都會讓它們產生(我可以想象這種情況)。

在註釋後編輯:如果在等待線程2的初始化完成時將消息傳遞給線程1,則可能會發生死鎖,特別是當消息有一些有界緩衝區或消息傳遞函數等待回覆。在這種情況下,我建議放棄等待線程2的想法,並且可能會傳遞一些在初始化完成時會從線程2調用的回調。