2016-03-03 44 views
-1

我正在研究一個「學生」線程將使用信號量喚醒「TA」線程的項目。sem_wait()似乎沒有真正在等待。我可能會做錯什麼?

我有一個名爲旗語studentNeedsHelp_Sem

sem_init(&studentNeedsHelp_Sem, 0 ,0);

初始化我的任何學生或TA線程甚至創建之前,我包括這3條線:

printf("DEBUG WAITING\n"); 
sem_wait(&studentNeedsHelp_Sem); 
printf("DEBUG DONE WAITING\n"); 

什麼發生:打印DEBUG WAITING,那麼我們必須等到學生真的需要幫助(並撥打sem_post(&studentNeedsHelp_Sem))才能看到DEBUG DONE WAITING

什麼發生:在我的學生線程開始之前都會打印出來。

(我用C工作OSX,使用POSIX並行線程)

謝謝您的幫助!

+0

'studentNeedsHelp_Sem'在哪裏申報?它沒有機會離開,是嗎? –

+0

@MartinJames在文件中通過'sem_t studentNeedsHelp_Sem;' –

+0

在全局很早就聲明瞭,好吧,我不得不問,信號正常,好吧,工作;) –

回答

3

檢查的sem_wait返回值(你應該始終做每當調用庫函數或系統調用)。這可能是負面的,表明有錯誤;看看errno或使用perror來顯示錯誤。如果是EDEADLK,我不會感到驚訝。

事實上,如果沒有線程已經啓動,那麼肯定沒有人會發布信號量。所以sem_wait永遠不會返回。這是一個僵局;你的程序正在等待可能永遠不會發生的事情。可能是因爲OSX的線程庫檢測到這個錯誤,並且sem_wait返回錯誤,假設這不是你想要的,並且至少如果sem_wait返回你的程序有機會恢復。

+0

雖然'sem_init'相同。我推薦使用'perror()' – Superlokkus

+0

你說得對,'sem_wait'返回-1。現在,這是一個爲什麼...我知道這會導致死鎖,我這樣做是爲了調試。但這是一個很好的觀點,也許編譯器看到了僵局並忽略了等待的呼叫。 –

+0

@Mriest:不是編譯器,而是線程庫或內核代碼。這是一次運行時檢查,而不是編譯時。 –

相關問題