(1)多線程資源競爭問題:
互斥:在多線程中對臨界資源的排他性訪問。
解決方案:互斥鎖
mutex互斥鎖在進程pcb塊,ret 為0說明別人在用,1說明空閑。
阻塞鎖
man pthread_mutex_init
man pthread_mutex_destory
定義:pthread_mutex_t ?mutex;內核對象
初始化:man pthread_mutex_init
加鎖 ?pthread_mutex_lock
解鎖 pthread_mutex_unlock
銷毀pthread_mutex_destroy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int WIN = 3; pthread_mutex_t mutex; void* th(void* arg) { while (1) { pthread_mutex_lock(&mutex); if (WIN > 0) { WIN--; printf("get win\n"); pthread_mutex_unlock(&mutex); int n = rand() % 5 + 1; sleep(n); pthread_mutex_lock(&mutex); WIN++; printf("relese win\n"); pthread_mutex_unlock(&mutex); break; } else { pthread_mutex_unlock(&mutex); } } return NULL; } int main(int argc, char** argv) { pthread_t tid[10] = {0}; int i = 0; pthread_mutex_init(&mutex,NULL); for (i = 0; i < 10; i++) { pthread_create(&tid[i], NULL, th, NULL); } for (i = 0; i < 10; i++) { pthread_join(tid[i], NULL); } pthread_mutex_destroy(&mutex); system("pause"); return 0; } |
為了并發要保證鎖定內容盡量少,可以快速完成,只鎖全局變量。沒有解鎖就會陷入死鎖。
加鎖后的代碼到解鎖部分屬于原子操作
?
(2)同步:有一定順序的對資源的排他性訪問(二值)
互斥鎖可以控制排他訪問,但沒有順序。
信號量:1/0 ? semaphore.h ?posix
定義:sem_t sem
初始化:int sem_init(,0線程用1進程用,1);,0,0
p申請sem_wait; ? ? ? ? ? ?p申請信號量會阻塞-1
v釋放sem_post ? ? ? ? ?v釋放信號量不阻塞+1 ? ?二值信號量
銷毀sem_destroy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <semaphore.h> sem_t sem_H,sem_W; void* th1(void* arg) { int i =10; while(i--) { sem_wait(&sem_H); // P 操作 也即是 申請信號量 會阻塞 -1 printf("hello "); fflush(stdout); sem_post(&sem_W); // V 操作 釋放信號量 +1 } return NULL; } void* th2(void* arg) { int i =10; while(i--) { sem_wait(&sem_W); printf("world\n"); sem_post(&sem_H); sleep(1); } return NULL; } int main(int argc, char **argv) { pthread_t tid1,tid2; sem_init(&sem_H,0,1); sem_init(&sem_W,0,0); pthread_create(&tid1,NULL,th1,NULL); pthread_create(&tid2,NULL,th2,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); sem_destroy(&sem_H); sem_destroy(&sem_W); system("pause"); return 0; } |
計數信號量是互斥
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <semaphore.h> sem_t sem_WIN; void* th(void* arg) { sem_wait(&sem_WIN); printf("get win\n"); int n = rand() % 5 + 1; sleep(n); printf("relese win\n"); sem_post(&sem_WIN); return NULL; } int main(int argc, char** argv) { pthread_t tid[10] = {0}; int i = 0; sem_init(&sem_WIN,0,3); for (i = 0; i < 10; i++) { pthread_create(&tid[i], NULL, th, NULL); } for (i = 0; i < 10; i++) { pthread_join(tid[i], NULL); } sem_destroy(&sem_WIN); system("pause"); return 0; } |
(3)死鎖產生條件:
互斥條件:一個資源每次只能被一個進程使用
請求與保持條件:一個進程因請求資源而阻塞時,對以獲得的資源保持不放。
不剝奪條件:進程以獲得的資源,未使用完不能強行剝奪。
循環等待條件:若干進線程之間形成頭尾相接的循環等待資源關系。
?