生产者消费者 && 哲学家就餐

本文是我对锁以及线程的学习,虽然代码都是参考其他人的,但是我还是在他们代码的基础上根据自己的想法修改了一些的,大家在学的时候也记得要多改改来看运行结果,这样学的快。

生产者消费者学习:
参考链接 生产者消费者–c语言实现

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h> 
#include<pthread.h>

pthread_mutex_t mtx;          // 互斥锁,保证只有一个线程访问共享资源
pthread_cond_t cond_add;      // 生产信号量
pthread_cond_t cond_del;      // 消费信号量

int pool;  // 资源池
int size;  // 资源池上限

#define THREADS 3              // 开辟的线程数
pthread_t tid_pd[THREADS];     // 生产者线程组
pthread_t tid_cs[THREADS];     // 消费者线程组

void producer(void* id)
{
	int threadid = *((int*)id);
	printf("producer thread( id: %d ) started.\n", threadid);
	while (1)
	{
		pthread_mutex_lock(&mtx);
		while (pool >= size) // 我是一直让它while了,直到通知已经生产了一个资源时才继续
		{
			pthread_cond_wait(&cond_del, &mtx);
		}

		++pool;
		printf("p%d add a good, pool is %d.\n", threadid, pool);

		pthread_cond_signal(&cond_add);
		pthread_mutex_unlock(&mtx);
	}
	return;
}

void consumer(void* id)
{
	int threadid = *((int*)id);
	printf("consumer thread( id: %d ) started.\n", threadid);
	while (1)
	{
		pthread_mutex_lock(&mtx);
		while (pool <= 0)
		{
			pthread_cond_wait(&cond_add, &mtx);
		}

		--pool;
		printf("\t\t\t c%d del a good, pool is %d.\n", threadid, pool);

		pthread_cond_signal(&cond_del);
		pthread_mutex_unlock(&mtx);
	}
	return;
}

int main(int argc, char const* argv[])
{
	// 给对于的锁及信号量开辟资源并初始化
	pthread_mutex_init(&mtx, NULL);
	pthread_cond_init(&cond_add, NULL);
	pthread_cond_init(&cond_del, NULL);

	pool = 0;
	size = 10;

	int i = 0;

	// 创建生产者、消费者的线程
	for (i = 0; i < THREADS; i++)
	{
		if (pthread_create(&tid_pd[i], NULL, (void*)producer, (void*)(&i)) != 0)
		{
			printf("create producer thread %d error!\n", i);
			return 0;
		}
		usleep(100000); // 让线程能有足够时间起来
	}
	for (i = 0; i < THREADS; i++)
	{
		if (pthread_create(&tid_cs[i], NULL, (void*)consumer, (void*)(&i)) != 0)
		{
			printf("create consumer thread %d error!\n", i);
			return 0;
		}
		usleep(100000);
	}

	// 依次对生产者、消费者线程进行退出
	for (i = 0; i < THREADS; i++)
	{
		if (pthread_join(tid_pd[i], NULL) != 0)
		{
			printf("join producer thread %d error!\n", i);
			return 0;
		}
	}
	for (i = 0; i < THREADS; i++)
	{
		if (pthread_join(tid_cs[i], NULL) != 0)
		{
			printf("join consumer thread %d error!\n", i);
			return 0;
		}
	}

	// 销毁开辟的锁及信号量的空间
	pthread_mutex_destroy(&mtx);
	pthread_cond_destroy(&cond_add);
	pthread_cond_destroy(&cond_del);

	return 0;
}

哲学家就餐:
参考链接 哲学家就餐问题(C语言实现)

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>

#define MAX_PHILOSOPHER_NUM    5

const char Philosopher[MAX_PHILOSOPHER_NUM + 1] = "ABCDE";

pthread_mutex_t chopstick[MAX_PHILOSOPHER_NUM + 1];

void* eat_think(void* arg)
{
	int left, right;  // 左右筷子的编号
	char phiName = *((char*)arg);
	switch (phiName) {
	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;
	}

	while (1)
	{
		usleep(3); //思考

		pthread_mutex_lock(&chopstick[left]);  // 拿起左手的筷子
		printf("Philosopher %c fetches chopstick %d\n", phiName, left);
		if (pthread_mutex_trylock(&chopstick[right]) != 0)  // 拿起右手的筷子
		{
			pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子
			continue;
		}
		//pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉
		printf("Philosopher %c fetches chopstick %d\n", phiName, right);

		printf("Philosopher %c is eating.\n", phiName);
		usleep(3); //吃饭

		pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子
		printf("Philosopher %c release chopstick %d\n", phiName, left);

		pthread_mutex_unlock(&chopstick[right]); //放下右手的筷子
		printf("Philosopher %c release chopstick %d\n", phiName, right);
	}
}

int main()
{
	int i;
	pthread_t Philosopher_t[MAX_PHILOSOPHER_NUM];  // 哲学家

	for (i = 0; i < MAX_PHILOSOPHER_NUM; ++i)
	{
		pthread_mutex_init(&chopstick[i], NULL);
		pthread_create(&Philosopher_t[i], NULL, eat_think, (void*)(&Philosopher[i]));
	}

	for (i = 0; i < MAX_PHILOSOPHER_NUM; ++i)
	{
		pthread_join(Philosopher_t[i], NULL);
	}

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值