1. 程式人生 > >執行緒安全與執行緒不安全

執行緒安全與執行緒不安全

基本概念

執行緒不安全:就是不提供資料訪問保護,在多執行緒環境中對資料進行修改,會出現資料不一致的情況。

執行緒安全:就是多執行緒環境中有對全域性變數的變動時,需要對執行的程式碼塊採用鎖機制,當一個執行緒訪問到某個資料時,其他執行緒需要等待當前執行緒執行完該程式碼塊才可執行,不會出現資料不一致或者資料被汙染。

如果一段程式碼在被多個執行緒執行,如果每次執行結果和單執行緒執行的結果是一樣的,而且其他變數的值和預期一樣,就是執行緒安全的。

執行緒安全主要由對有全域性變數或靜態變數有修改動作而引起的。

小實驗

描述:

首先建立兩個執行緒,執行同一段程式碼對全域性變數count進行修改操作,這裡是進行++5000次並列印,我們預期的結果應該是10000,分別線上程安全和執行緒不安全執行對比。

我們在讀取變數的值和把變數的新值儲存回去,這兩個之間插入一個printf呼叫,它會呼叫write系統呼叫,此時會從使用者態進入核心態,為核心排程別的執行緒執行提供了一個很好的時機。

執行緒不安全

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

int count = 1;

void* run(void * arg1)
{
    int i = 0;
    while(1)
    {
        int val = count;
        i++;
        printf("count is %d  \n"
, count); count = val+1; if(5000 == i) break; } } int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, run, NULL); pthread_create(&tid2, NULL, run, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; }

重複執行執行多次觀察結果:
第一次

1
第二次
2

我們發現線上程不安全的情況下,執行結果不符合預期。

執行緒安全下:

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

int count = 1;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* run(void * arg1)
{
    int i = 0;
    pthread_mutex_lock(&mutex);
    while(1)
    {
        int val = count;
        i++;
        printf("count is %d  \n", count);
        count = val+1;
        if(5000 == i)
            break;
    }
    pthread_mutex_unlock(&mutex);
}


int main()
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, run, NULL);
    pthread_create(&tid2, NULL, run, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}

我們通過引入互斥鎖(Mutex),使得一個時刻只能有一個執行緒進入程式碼塊,從而達到執行緒安全的目的。

結果:
1