執行緒安全與執行緒不安全
阿新 • • 發佈:2019-02-16
基本概念
執行緒不安全:就是不提供資料訪問保護,在多執行緒環境中對資料進行修改,會出現資料不一致的情況。
執行緒安全:就是多執行緒環境中有對全域性變數的變動時,需要對執行的程式碼塊採用鎖機制,當一個執行緒訪問到某個資料時,其他執行緒需要等待當前執行緒執行完該程式碼塊才可執行,不會出現資料不一致或者資料被汙染。
如果一段程式碼在被多個執行緒執行,如果每次執行結果和單執行緒執行的結果是一樣的,而且其他變數的值和預期一樣,就是執行緒安全的。
執行緒安全主要由對有全域性變數或靜態變數有修改動作而引起的。
小實驗
描述:
首先建立兩個執行緒,執行同一段程式碼對全域性變數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;
}
重複執行執行多次觀察結果:
第一次
第二次
我們發現線上程不安全的情況下,執行結果不符合預期。
執行緒安全下:
#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),使得一個時刻只能有一個執行緒進入程式碼塊,從而達到執行緒安全的目的。
結果: