多線程共享一個進程的地址空間雖然線程間通信容易進行,但是多線程同時訪問共享對象時需要引入同步和互斥機制。
1.線程間的互斥,引入互斥鎖的目的是用來保證共享資源數據操作的完整性。
互斥鎖主要用來保護臨界資源,每個鄰界資源都由一個互斥鎖來保護,任何時刻最多只能有一個線程能訪問該資源。線程必須先獲得互斥鎖才能訪問臨界資源,訪問完臨界資源后釋放該鎖。如果無法獲得鎖,線程會阻塞知道獲得鎖為止。
2同步指的是多個任務按照約定的順序相互配合完成一件事情,
1 #include<stdio.h> 2 #include<pthread.h> 3 int g_count=0; 4 void* pthread_run(void* arg) 5 { 6 int count=5000; 7 int tmp; 8 while(count--) 9 { 10 tmp=g_count; 11 printf("pthread_id:%d ,g_count: %d\n",(int)arg,tmp); 12 g_count=tmp+1; 13 } 14 return (void*)0; 15 } 16 int main() 17 { 18 pthread_t tid1,tid2; 19 pthread_create(&tid1,NULL,pthread_run,(void*)1); 20 pthread_create(&tid2,NULL,pthread_run,(void*)2); 21 sleep(1); 22 printf("finally,g_count: %d\n",g_count); 23 return 0; 24 }
按照預期結果,應該打印出10000,把g_count加10000次
但是,
這是因為兩個線程同時對全局變量進行操作時產生干擾。
多線程的互斥操作主要用互斥量來實現,保護臨界資源,對臨界區加鎖。
#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);//attr一般使用默認值為NULL
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
加鎖,去鎖函數
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);//阻塞式
int pthread_mutex_trylock(pthread_mutex_t *mutex);//非阻塞式
int pthread_mutex_unlock(pthread_mutex_t *mutex);
實現加鎖
1 #include<stdio.h> 2 #include<pthread.h> 3 pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 4 int g_count=0; 5 void* pthread_run(void* arg) 6 { 7 int count=5000; 8 int tmp; 9 while(count--) 10 { 11 pthread_mutex_lock(&mutex); 12 tmp=g_count; 13 printf("pthread_id:%d ,g_count: %d\n",(int)arg,tmp); 14 g_count=tmp+1; 15 pthread_mutex_unlock(&mutex); 16 } 17 return (void*)0; 18 } 19 int main() 20 { 21 pthread_t tid1,tid2; 22 pthread_create(&tid1,NULL,pthread_run,(void*)1); 23 pthread_create(&tid2,NULL,pthread_run,(void*)2); 24 sleep(1); 25 pthread_mutex_destroy(&mutex); 26 printf("finally,g_count: %d\n",g_count); 27 return 0; 28 }
總結:加鎖時應該考慮問題的規模選擇加鎖的粒度,應從安全,性能,穩定性三方面來考慮。
加鎖時,粒度越大,申請鎖的次數少,申請鎖時會占代碼資源;
加鎖加的越早,并行性能降低,程序執行效率也隨之降低。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。