posix信号量以及互斥量实现哲学家就餐问题
1.哲学家就餐问题描述(请参考请参考其他博主)
2.如何实现就餐场景
a.5个信号量代表5支筷子
b.5五个线程代表5个哲学家
c.主线程负责创建筷子们和哲学家们
d.sem_wait函数 模拟拿筷子
3.可能出现同时拿筷子的情况,这时哲学家们依次等待
4.解决方案之一,让其中一人反向拿筷子(程序中为第五个)
5.同理,将信号量的创建和使用改成互斥量即可实现互斥量实现哲学家就餐问题模拟
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
sem_t sem[5];
void err_pthread(int ret, char *str)
{
if(ret != 0)
{
fprintf(stderr,"%s:%s\n",str,strerror(ret));
//pthread_exit(NULL);
exit(1);
}
}
void sys_err(char *str)
{
perror(str);
exit(1);
}
#define DELAY (sleep(rand() % 3))
void *thread_func(void *arg)
{
long i = (long) arg;
while(1)
{
/*解决方法
if (i == 4)
{
printf("thread No.%ld thinking\n",i+1);
DELAY ;
printf("thread No.%ld hungry\n",i+1);
sem_wait(&sem[(i+1 ) % 5]);
DELAY ;
sem_wait(&sem[i]);
printf("thread No.%ld eating\n",i+1);
DELAY ;
sem_post(&sem[i]);
sem_post(&sem[(i+1 ) % 5]);
DELAY ;
}
else {*/
printf("thread No.%ld thinking\n",i+1);
DELAY ;
printf("thread No.%ld hungry\n",i+1);
sem_wait(&sem[i]);拿左筷子
DELAY ;
sem_wait(&sem[(i+1 ) % 5]);拿右筷子
printf("thread No.%ld eating\n",i+1);
DELAY ;
sem_post(&sem[(i+1 ) % 5]);
sem_post(&sem[i]);
DELAY ;
//}
}
return NULL;
}
int main(void)
{
long i;
int ret;
pthread_t tid[5];
//init sem and threads
//创建 信号量和线程
for(i = 0; i<5;i++)
{
ret = sem_init(&sem[i], 0, 1);
if(ret != 0)
sys_err("mutex init");
}
for(i=0; i<5; i++)
{
ret = pthread_create(&tid[i], NULL, thread_func, (void *) i);
if(ret != 0)
err_pthread(ret, "thread_create");
// printf("tid[%ld] = %lu\n",i,tid[i]);
}
//信号量销毁和线程回收
for(i=0;i<5;i++)
{
int r;
r=pthread_join(tid[i],NULL);
if (r!=0)
printf("failed join!\n");
else
printf("thread No.%ld\n",i);
}
for(i = 0;i<5;i++)
{
sem_destroy(&sem[i]);
printf("%ld had been destoyed\n",i);
}
return 0;
}