示例考慮將有兩個執行緒 T1 和 T2

你怎麼發現它們?

如果多個執行緒可以訪問相同的變數/資源/記憶體位置,並且至少執行緒正在更改變數/資源/記憶體位置的值,則可能發生 Race Condition 。因為如果一個執行緒正在改變變數/資源/記憶體位置的值而另一個執行緒試圖讀取相同的值,那麼它將不會獲得更新的值。

注意 :如果所有執行緒只是讀取*變數/資源/記憶體位置,*則不會發生 Race Condition

示例:程式受 Race Race 影響

#include <stdio.h>
#include <pthread.h>

int x= 0;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        x++;
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

我螢幕上的輸出是:

Point 1 >> X is: 0
Point 2 >> X is: 9925047

你的輸出會有所不同。但肯定不會是 20,000,000。由於兩個執行緒執行相同的迴圈並具有全域性變數 int x;

for ( i = 0; i < 10000000; i++ )
{
   x++; 
}

所以 x 線上 Point 2 >> X is: 9925047 的最終值應該是 20,000,000。但事實並非如此。

在讀取 x 和寫回 x 之間的時間內,x 的狀態可以被另一個執行緒更改。

假設一個執行緒檢索 x 的值,但尚未儲存它。另一個執行緒也可以檢索相同的 x 值(因為還沒有執行緒改變它),然後它們都將相同的值(x + 1)儲存回 x!

例:

執行緒 1:讀取 x,值為 7

執行緒 1:將 x 加 1,值現為 8

執行緒 2:讀取 x,值為 7

執行緒 1:在 x 中儲存 8

執行緒 2:將 x 加 1,值現為 8

執行緒 2:在 x 中儲存 8

你怎麼處理它們?

通過在訪問共享資源或互斥的程式碼之前採用某種鎖定機制,可以避免競爭條件。

以下是修改後的程式:

示例:已解決競爭條件問題

#include <stdio.h>
#include <pthread.h>

int x= 0;
//Create mutex
pthread_mutex_t test_mutex;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        //Lock mutex before going to change variable
        pthread_mutex_lock(&test_mutex);
        x++;
        //Unlock mutex after changing the variable
        pthread_mutex_unlock(&test_mutex);
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    //Initlize mutex
    pthread_mutex_init(&test_mutex, NULL);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    //Destroy mutex after use
    pthread_mutex_destroy(&test_mutex);
    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

以下是輸出:

Point 1 >> X is: 0
Point 2 >> X is: 20000000

在這裡,答案每次都是 20,000,000。

注意 :修改後的程式沒有競爭條件錯誤,執行起來需要很長時間。因為 mutex 鎖定和解鎖有負擔。