代码记录:
5个人(使用线程模拟)用5支筷子吃饭的问题。
需要解决的问题:
- 等所有人吃完就终止
- 防止死锁
使用到的知识:
- pthread
- pthread_mutex_trylock
- 非阻塞尝试加锁,成功返回0
- pthread_mutex_unlock
- 解除锁
- pthread_create(&mThread[i],NULL,thread_do,&index_arr[i])
- 创建进程,参数分别为
线程地址,attr,启动函数,启动参数(void *)
- 创建进程,参数分别为
- pthread_join(mThread[i],NULL);
- pthread_mutex_trylock
- unistd.h
- POSIX API中的sleep函数
PS:引入AND信号量,避免产生环路等待。(申请多个,只要没有全部申请到就丢弃,重新申请)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/malloc.h>
#define PEO_NUM 5
#define EAT_SEC 3
#define WAIT_SEC 1
#define OK 0
#define ERR -1
pthread_mutex_t chopstick[5];
pthread_mutex_t * getStickIndex(int index){
return &chopstick[index];
}
void dropStick(int stick_num){
if(pthread_mutex_unlock(&chopstick[stick_num])){
printf("错误:筷子%d放不下了!",stick_num);
}
}
int takeStick(int stick_n1,int stick_n2){
//printf("尝试去拿筷子%d\n",stick_num);
UNLOCK_N1:
while(pthread_mutex_trylock(&chopstick[stick_n1])){
sleep(WAIT_SEC);
}
UNLOCK_N2:
while(pthread_mutex_trylock(&chopstick[stick_n2])){
//把前面获得的筷子扔了
sleep(WAIT_SEC);
printf("拿不到%d号筷子,于是把%d号筷子扔了了事\n",stick_n2,stick_n1);
dropStick(stick_n1);
goto UNLOCK_N1;
}
return OK;
}
void eat(){
// sleep for sec
sleep(EAT_SEC);
}
void * thread_do(void * arg){
int _THREAD_NUM=*(int*)arg;
//printf("线程%d报道~\n",_THREAD_NUM);
takeStick(_THREAD_NUM,(_THREAD_NUM+1)%PEO_NUM);
//拿到了_THREAD_NUM筷子
printf("线程%d正在恰饭\n",_THREAD_NUM);
eat();
dropStick(_THREAD_NUM);
dropStick((_THREAD_NUM+1)%5);
return NULL;
}
int main(){
int index_arr[5]={0,1,2,3,4};
//初始化资源
for (int i = 0; i < 5; i++)
{
pthread_mutex_init(&chopstick[i],NULL);
}
//构造线程
pthread_t mThread[5];
for(int i=0;i<5;i++){
if (pthread_create(&mThread[i],NULL,thread_do,&index_arr[i]) == 0)
{
//printf("线程%d 创建成功!\n",i);
}
}
for (int i = 0; i < 5; i++)
{
//printf("主线程正在等待%d号子线程\n",i);
pthread_join(mThread[i],NULL);
//printf("线程%d已退出!\n",i);
}
return 0;
}