2014-03-25 53 views
1

這是互斥鎖的經典示例。我不知道爲什麼下面的代碼不起作用,即。它不會每次都打印「ctr = 0」(但是,例如,ctr = 535)。兩個線程,第一個添加第二個替代品

int ctr; 
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 

void * add (void * arg_wsk) 
{ 
     int i; 
     for (i = 0; i < 100000; i++) { 
       pthread_mutex_lock (&m); 
       ctr++; 
       pthread_mutex_unlock (&m); 
     } 
     return(NULL); 
} 

void * sub(void * arg_wsk) 
{ 
     int i; 
     for (i = 0; i < 100000; i++) { 
       pthread_mutex_lock (&m); 
       ctr--; 
       pthread_mutex_unlock (&m); 
     } 
     return(NULL); 
} 
int main() 
{  
     pthread_t tid1, tid2; 
     int i; 
     void *res; 
     ctr = 0; 
     pthread_mutex_init(&m, NULL); 

     pthread_create(&tid1, NULL, add, NULL); 
     pthread_detach(tid1); 

     pthread_create(&tid2, NULL, sub, NULL); 
     pthread_detach(tid2); 

     pthread_join(tid1, &res); 
     pthread_join(tid2, &res); 

     pthread_mutex_destroy(&m); 
     printf("ctr = %d", ctr); 
     pthread_exit(NULL); 
} 

你能指點我正確的方向嗎?

此外,stackoverflow告訴我提供一些更多的細節,我的問題主要是代碼。但是我真的不知道在這裏寫什麼,我只是希望當我有更多的聲望時這條消息會消失。

+0

未能檢查任何pthread庫返回值意味着您可能忽略了一個重要的錯誤。 – kmarsh

回答

4

我認爲你濫用POSIX API。如果你分離線程,你不應該加入它們。刪除分離,看看這是否改善了事情。我想你會看到main()現在阻塞,直到線程完成。

還要注意,從的鏈接加入通話

ESRCH No thread could be found corresponding to that specified by the 
      given thread ID. 

如果你幸運的話,你會打這個。如果你不幸運,瘋狂的事情會發生。不要在同一個線程上混合分離和加入調用。

https://computing.llnl.gov/tutorials/pthreads/#Joining

+1

是的,它爲我修好了。 – kmarsh

+0

解決了這個問題,您還應該研究如何將參數傳遞給線程。如果你在'main()'中使ctr成爲一個局部變量,並將調用改爲'pthread_create(&tid1,NULL,add,&ctr)',我會將其視爲更具可讀性的代碼。 – Trygve

+0

我錯誤地認爲「分離」意味着什麼。謝謝。 – Matt

1

您的計數器ctr的值取決於兩個線程完成其完整的執行。

根據pthread_detach(3)

一旦一個線程已被分離,它不能與 在pthread_join接合(3)或再次作出可連接。

如果您從程序中刪除pthread_detach調用,您將獲得預期的輸出。

此外,考慮明確創建您的線程可連接(或分離)的便攜性。

+0

你是對的,但除了「不要脫離線程」之外,還有其他方法可以解決問題。這實際上只不過是線程同步的另一點,其中pthread_join(如果可能,在這種情況下不可能如您所指出的那樣)是一種同步形式。 – mah

相關問題