簡體   English   中英

全局變量未在線程中更改?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM