[英]Global variable not changing in thread?
我正在嘗試更新main函數中的全局變量,並有一個線程告訴我該變量何時為正。
代碼: https : //pastebin.com/r4DUHaUV
當我運行它時,雖然1和2應該是正確的答案,但只有2個出現。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_t tid;
pthread_mutex_t mtx;
pthread_cond_t cond;
int nr=0;
void* function(void* arg)
{
pthread_mutex_lock(&mtx);
printf("Number in thread : %d \n",nr);
while(nr<=0)
pthread_cond_wait(&cond,&mtx);
printf("Number %d is positive \n",nr);
pthread_mutex_unlock(&mtx);
}
int main()
{
pthread_mutex_init(&mtx,NULL);
pthread_create(&tid,NULL,function,NULL);
int i;
for(i=0;i<3;i++)
{
int isPos=0;
pthread_mutex_lock(&mtx);
if(i==0)
nr=nr+1;
if(i==1)
nr=nr-2;
if(i==2)
nr=nr+3;
if(nr>0)
isPos=1;
if(isPos==1)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx);
}
pthread_join(tid,NULL);
return 0;
}
正如我在一般性評論中提到的那樣,我將在這里重復:
無法保證主線程不會關閉,鎖定互斥鎖,更改nr,發信號給cv(無論是否有人在等待它)以及解鎖互斥鎖,所有這些操作都在子線程甚至鎖定互斥鎖之前就已經完成,開始等待簡歷的機會要少得多。 在這種情況下,當孩子最終獲得互斥量時,nr可以為1(或2,依此類推)。 這意味着您的while循環將被跳過(nr <= 0是不正確的),無論當前nr的值是什么,都會在輸出時打印出來。 我已經運行了幾次,並多次獲得1x1、1x2和2x2。
一個簡單的解決方法是使用您設置的cv / mtx對來監視main
更改,也可以監視function
啟動-啟動。 首先是代碼:
編碼
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int nr = -1;
void* function(void* arg)
{
// signal main to start up once we start waiting
pthread_mutex_lock(&mtx);
nr = 0;
pthread_cond_signal(&cond);
// now start waiting (which will unlock the mutex as well, which means
// the main thread will be be able to acquire it and check nr safely
while(nr<=0)
pthread_cond_wait(&cond,&mtx);
printf("Number %d is positive \n",nr);
pthread_mutex_unlock(&mtx);
return NULL;
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,function,NULL);
// wait until child is knowingly waiting
pthread_mutex_lock(&mtx);
while (nr != 0)
pthread_cond_wait(&cond, &mtx);
pthread_mutex_unlock(&mtx);
// now we know the child is ready to receive signals
int i;
for(i=0;i<3;i++)
{
pthread_mutex_lock(&mtx);
if(i==0)
nr=nr+1;
if(i==1)
nr=nr-2;
if(i==2)
nr=nr+3;
int isPos = (nr>0);
pthread_mutex_unlock(&mtx);
if (isPos)
pthread_cond_signal(&cond);
}
pthread_join(tid,NULL);
return 0;
}
這個怎么運作
nr
的初始值確定為-1
。 只有子線程會將其直接更改為0
,即使在子謂詞互斥的保護下也是如此。
// signal main to start up once we start waiting
pthread_mutex_lock(&mtx);
nr = 0;
pthread_cond_signal(&cond);
請注意,在上述三行之后,孩子仍然擁有互斥體。 它以原子方式釋放它, 並在進入下一個循環的第一個條目時開始等待通知:
while(nr<=0)
pthread_cond_wait(&cond,&mtx);
現在,回到main
,啟動程序將創建子線程,獲取互斥量,然后進行監視直到nr
為零。
pthread_create(&tid,NULL,function,NULL);
// wait until child is knowingly waiting
pthread_mutex_lock(&mtx);
while (nr != 0)
pthread_cond_wait(&cond, &mtx);
pthread_mutex_unlock(&mtx);
使它通過的唯一方法是當nr == 0
。 發生這種情況時,孩子必須更改它,但更重要的是,它還必須等待條件變量(這就是我們獲得互斥鎖的方式;還記得嗎?)從那時起,代碼是相似的。 值得注意的是,我使用pthread初始化程序來確保互斥體和cvar正確站立。 您的原始帖子缺少cvar初始化。
最后,做多謂雙責與單CVaR的-MTX對容易陷入困境,並且可以防不勝防邊緣情況下,當你做了(陷入困境,那是)。 小心。 這個特定的示例是任務的交接順序,而不是同時執行的任務,這使其顯得微不足道,因此我很樂意演示它。
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.