1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <pthread.h>
5 #include <semaphore.h>
6
7 #define PHILOSOPHER_NUM 5
8 #define THINKING 0
9 #define HUNGRY 1
10 #define EATING 2
11
12 pthread_mutex_t mutex;
13 sem_t semph[PHILOSOPHER_NUM];
14 #define LEFT (i + PHILOSOPHER_NUM -1)%PHILOSOPHER_NUM //i 的左领居编号
15 #define RIGHT (i + 1)%PHILOSOPHER_NUM //i 的右领居编号
16 int state[PHILOSOPHER_NUM];
extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value)); T>
sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。
函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。它作用是给信号量的值加上一个“1”,它是一个“原子操作”,即同时对同一个信号量做加“1”操作的两个线程是不会冲突的。而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。
函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,介信号量的值将减到1。如果对一个值为0的信号量调用
sem_wait(),这个函数就会地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。
函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。
函数sem_destroy(sem_t *sem)用来释放信号量sem。
1 void think(int i)
2 {
3 }
4
5 void eat(int i)
6 {
7 }
8
9 void test(int i)
10 {
11 if((state[i] == HUNGRY )
12 && (state[LEFT] != EATING)
13 && (state[RIGHT]!= EATING))
14 {
15 state[i] = EATING;
16
17 sem_post(&semph[i]);
18 }
19 }
20
21
22
23 void take_forks(int i)
24 {
25 pthread_mutex_lock(&mutex);
26 state[i] = HUNGRY;
27 test(i);
28 pthread_mutex_unlock(&mutex);
29 sem_wait(&semph[i]);
30 }
31
32 void put_forks(int i)
33 {
34 pthread_mutex_lock(&mutex);
35 state[i] = THINKING;
36 test(LEFT);
37 test(RIGHT);
38 pthread_mutex_unlock(&mutex);
39 }
40
41
42 void philosopher(int *index)
43 {
44 int mythreadId = (*index);
45 int sleepTime;
46 bzero(state,0);
47
48 while(1)
49 {
50 think(mythreadId);
51 take_forks(mythreadId);
52 eat(mythreadId);
53 put_forks(mythreadId);
54
55 // sleep a random time : between 1 - 5 s
56 sleepTime = 1 + (int)(5.0*rand()/(RAND_MAX+1.0));
57 usleep(sleepTime*10);
58 }
59 }
1 int main()
2 {
3 int i,ret;
4 int threadId[PHILOSOPHER_NUM];
5 int errNum=0;
6 pthread_t t_phThread[PHILOSOPHER_NUM];
7 pthread_t t_threadInfo;
8
9 srand(getpid());
10 pthread_mutex_init(&mutex,NULL);
11
12 //ret = pthread_create(&t_threadInfo, NULL, (void *) threadInfo, (void *) NULL);
13 if( ret )
14 {
15 errNum++;
16 }
17
18 for(i=0;i<PHILOSOPHER_NUM;i++)
19 {
20 threadId[i] = i;
21 sem_init(&semph[i],0,1);
22 ret=pthread_create(&t_phThread[i], NULL, (void *)philosopher, (void*)(&threadId[i]));
23 if(ret)
24 {
25 errNum++;
26 }
27
28 usleep(20);
29 }
30 if(errNum)
31 {
32 printf("thread create err! errnum=%d \n",errNum);
33 }
34
35 sleep(1);
36 }
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn) (void*),void *restrict arg);
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <pthread.h>
5 #include <semaphore.h>
6
7 #define PHILOSOPHER_NUM 5
8 #define THINKING 1
9 #define HUNGRY 2
10 #define EATING 3
11
12 pthread_mutex_t mutex;
13 sem_t semph[PHILOSOPHER_NUM];
14
15 void philosopher(int *index)
16 {
17 int mythreadId;
18 char myState,strState[128];
19 int leftIndex;
20 int rightIndex;
21 int sleepTime;
22
23 mythreadId = (*index);
24 leftIndex = mythreadId + PHILOSOPHER_NUM-1)% PHILOSOPHER_NUM;
25 rightIndex = (mythreadId + 1) % PHILOSOPHER_NUM;
26
27 myState = THINKING;
28
29 while(1)
30 {
31 switch(myState)
32 {
33 case THINKING:
34 myState = HUNGRY;
35 strcpy(strState,"HUNGRY");
36 break;
37 case HUNGRY:
38 strcpy(strState,"HUNGRY");
39 if(!(sem_wait(&semph[leftIndex])))
40 {
41 if(!(sem_wait(&semph[rightIndex])))
42 {
43 myState = EATING;
44 strcpy(strState,"EATING");
45 }
46 else
47 {//不能同时拿起则都不拿起
48 sem_post(&semph[leftIndex]);
49 }
50 }
51 break;
52 case EATING:
53 sem_post(&semph[leftIndex]);
54 sem_post(&semph[rightIndex]);
55
56 myState=THINKING;
57 strcpy(strState,"THINKING");
58 break;
59 }
60 pthread_mutex_lock(&mutex);
61 printf("pholosopher %d begin %s\n",mythreadId,strState);
62 pthread_mutex_unlock(&mutex);
63
64 sleepTime = 1+(int)(5.0*rand()/(RAND_MAX+1.0));
65 usleep(sleepTime);
66
67 }
68 }
69
70 int main()
71 {
72 int i,ret;
73 int threadId[PHILOSOPHER_NUM];
74 int errNum=0;
75 pthread_t t_phThread[PHILOSOPHER_NUM];
76 //pthread_t t_threadInfo;
77
78 srand(getpid());
79 pthread_mutex_init(&mutex,NULL);
80 for(i=0;i<PHILOSOPHER_NUM;i++)
81 {
82 threadId[i] = i;
83 sem_init(&semph[i],0,1);
84 ret=pthread_create(&t_phThread[i], NULL, (void *)philosopher, (void*)(&threadId[i]));
85 if(ret)
86 {
87 errNum++;
88 }
89
90 usleep(20);
91 }
92 if(errNum)
93 {
94 printf("thread create err! errnum=%d \n",errNum);
95 }
96
97 sleep(1);
98 }