嵌入式自学第三十天(5.28)
(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)死锁产生条件:
互斥条件:一个资源每次只能被一个进程使用
请求与保持条件:一个进程因请求资源而阻塞时,对以获得的资源保持不放。
不剥夺条件:进程以获得的资源,未使用完不能强行剥夺。
循环等待条件:若干进线程之间形成头尾相接的循环等待资源关系。