哲学家问题:
哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <signal.h>
#include <sys/types.h>
#include <ctype.h>
pthread_mutex_t chopstick[6]; // 定义锁
void get(int *left,int *right,char phi) {
switch (phi){
case 'A':
*left = 5;
*right = 1;
break;
case 'B':
*left = 1;
*right = 2;
break;
case 'C':
*left = 2;
*right = 3;
break;
case 'D':
*left = 3;
*right = 4;
break;
case 'E':
*left = 4;
*right = 5;
break;
}
}
void *eat_think(void *arg)
{
char phi = *(char *)arg;
int left,right;
get(&left,&right,phi); //让每个哲学家确认自己需要的是那两根筷子
for(;;){
usleep(20000);
pthread_mutex_lock(&chopstick[left]); //首先拿到左边的筷子,并上锁,保证这个筷子不会被左边的哲学家拿到
printf("Philosopher %c fetches chopstick %d\n", phi, left); //输出这个筷子正在被使用
if (pthread_mutex_trylock(&chopstick[right]) ==EBUSY){
//给右边的筷子加锁并判断是否正在被右边的哲学家使用
pthread_mutex_unlock(&chopstick[left]); //如果是则解开左边的锁,并跳过该次循环
continue;
}
printf("Philosopher %c fetches chopstick %d\n", phi,right); //如果右边的筷子没有被使用则使用,并输出这个筷子正在被使用
printf("Philosopher %c is eating.\n",phi); //当哲学家拿到两个筷子时,则开始吃饭
usleep(20000);
pthread_mutex_unlock(&chopstick[left]); //解锁左边的筷子
printf("Philosopher %c release chopstick %d\n", phi,left); //输出左边的筷子可以被别人使用
pthread_mutex_unlock(&chopstick[right]); //解锁右边的筷子
printf("Philosopher %c release chopstick %d\n", phi,right); //输出右边的筷子可以被别人使用
}
}
int main(){
pthread_t A,B,C,D,E; //5个哲学家
int i;
for (i = 0; i < 5; i++)
pthread_mutex_init(&chopstick[i],NULL); //初始化锁
pthread_create(&A,NULL, eat_think, (void *)"A"); //初始化五个线程,同时调用eat_think函数,用A到E分别作为参数,代表五个哲学家
pthread_create(&B,NULL, eat_think, (void *)"B");
pthread_create(&C,NULL, eat_think, (void *)"C");
pthread_create(&D,NULL, eat_think, (void *)"D");
pthread_create(&E,NULL, eat_think, (void *)"E");
pthread_join(A,NULL); //等待线程结束
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_join(E,NULL);
return 0;
}
生产者消费者问题:
生产者每次生产一个产品,消费这每次消耗一个产品。当消费者发现产品为0时,则阻塞等待生产者生产产品,生产者生产一个产品后,发出signal信号。而当产品累积到一定数目后,生产者打开锁,等待1秒,然后解锁,跳过本次循环。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *custom(void *arg)
{
while (1) {
pthread_mutex_lock(&mutex); //整个消费过程加锁
if ( count == 0 ) {
//判断是否有产品,没有则阻塞等待生产者生产产品并发出signal
printf("count is 0\n");
pthread_cond_wait(&cond, &mutex);
}
count--; //产品减一
printf("custom id is %lu, count is %d\n", pthread_self(), count);
pthread_mutex_unlock(&mutex);
sleep(1);
}
pthread_exit(0);
}
void *produce(void *arg)
{
while (1) {
pthread_mutex_lock(&mutex); //生产过程也要加锁
if ( count >= 10 ) {
//判断产品是否累积过多
printf("produce is too more\n");
pthread_mutex_unlock(&mutex); //解锁等待并且跳过循环
sleep(1);
continue;
}
count++; //产品加一
printf("produce id is %lu, count is %d\n", pthread_self(), count);
pthread_cond_signal(&cond); //有产品就发送信号给消费者
pthread_mutex_unlock(&mutex);
sleep(1);
}
pthread_exit(0);
}
int main()
{
pthread_t custom1, custom2, produce1, produce2, produce3;
pthread_create(&custom1, NULL, custom, NULL); //创建消费者和生产者
pthread_create(&custom2, NULL, custom, NULL);
sleep(3);
pthread_create(&produce1, NULL, produce, NULL);
pthread_create(&produce2, NULL, produce, NULL);
pthread_create(&produce3, NULL, produce, NULL);
pthread_join(custom1, NULL); //等待线程结束
pthread_join(custom2, NULL);
pthread_join(produce1, NULL);
pthread_join(produce2, NULL);
pthread_join(produce3, NULL);
return 0;
}