经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题

1.生产者-消费者问题

/*===============================================================

 * File Name : producerConsumerProblem.c
 * Creation Date : 2013-04-11
 * Last Modified : 2013年04月11日 星期四 20时53分13秒
 * Purpose :test linux semaphore usage

================================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>

void *producer_handler(void *ptr);
void *consumer_handler(void *ptr);

sem_t mutex,blank,fill;
int *buffer;
int in=0,out=0,buffer_size=10;

void main()
{
	if((buffer=(int *)malloc(buffer_size*sizeof(int)))==NULL)
		printf("can't allocate memroy on heap\n");
	sem_init(&mutex,0,1);
	sem_init(&blank,0,buffer_size);
	sem_init(&fill,0,0);

	int err;
	pthread_t
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
1. 生产者消费者问题 生产者消费者问题是一种经典同步问题,其中生产者线程将数据添加到共享缓冲区中,而消费者线程从该缓冲区中获取数据。为了避免竞争条件和死锁,我们需要使用信号量来解决这个问题。 使用两个信号量,一个用于表示缓冲区是否为空,另一个用于表示缓冲区是否已满。当缓冲区已满时,生产者将等待,直到缓冲区不再满。当缓冲区为空时,消费者将等待,直到缓冲区中有更多数据。 以下是用信号量解决生产者消费者问题的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; sem_t empty, full; int in = 0, out = 0; void *producer(void *arg) { int item; while (1) { item = rand() % 100; sem_wait(&empty); buffer[in] = item; printf("Producer produced item %d at %d\n", item, in); in = (in + 1) % BUFFER_SIZE; sem_post(&full); } } void *consumer(void *arg) { int item; while (1) { sem_wait(&full); item = buffer[out]; printf("Consumer consumed item %d at %d\n", item, out); out = (out + 1) % BUFFER_SIZE; sem_post(&empty); } } int main() { sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); pthread_t producer_thread, consumer_thread; pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); sem_destroy(&empty); sem_destroy(&full); return 0; } ``` 2. 哲学家进餐问题 哲学家进餐问题是一个经典同步问题,其中有五个哲学家围坐在圆桌旁,每个哲学家需要交替地思考和进餐。他们之间共享五个叉子,每个哲学家需要两个叉子才能进餐。 使用信号量来解决哲学家进餐问题。每个叉子都有一个信号量,当哲学家想要使用叉子时,他必须先获取左边的叉子,然后获取右边的叉子。当哲学家用完叉子时,他将释放两个叉子的信号量。 以下是用信号量解决哲学家进餐问题的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define NUM_PHILOSOPHERS 5 sem_t forks[NUM_PHILOSOPHERS]; pthread_mutex_t mutex; void *philosopher(void *arg) { int id = *(int *)arg; int left = id; int right = (id + 1) % NUM_PHILOSOPHERS; while (1) { // think printf("Philosopher %d is thinking\n", id); sleep(rand() % 3); // pick up forks pthread_mutex_lock(&mutex); sem_wait(&forks[left]); sem_wait(&forks[right]); pthread_mutex_unlock(&mutex); printf("Philosopher %d is eating\n", id); sleep(rand() % 3); // put down forks sem_post(&forks[left]); sem_post(&forks[right]); } } int main() { int ids[NUM_PHILOSOPHERS]; pthread_t philosophers[NUM_PHILOSOPHERS]; pthread_mutex_init(&mutex, NULL); for (int i = 0; i < NUM_PHILOSOPHERS; i++) { sem_init(&forks[i], 0, 1); ids[i] = i; pthread_create(&philosophers[i], NULL, philosopher, &ids[i]); } for (int i = 0; i < NUM_PHILOSOPHERS; i++) { pthread_join(philosophers[i], NULL); sem_destroy(&forks[i]); } pthread_mutex_destroy(&mutex); return 0; } ``` 3. 读者写者问题 读者写者问题是一个经典同步问题,其中有多个读者写者同时访问共享资源。多个读者可以同时读取共享资源,但是只有一个写者可以写入共享资源。当写者正在写入共享资源时,其他读者写者都需要等待。 使用信号量来解决读者写者问题。使用两个信号量,一个用于表示共享资源是否正在被写入,另一个用于表示读者数量。当写者正在写入共享资源时,所有请求访问共享资源的读者写者都需要等待。当有读者正在读取共享资源时,所有写者都需要等待。当没有写者正在写入共享资源并且没有读者正在读取共享资源时,写者可以开始写入共享资源。 以下是用信号量解决读者写者问题的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define NUM_READERS 5 #define NUM_WRITERS 2 int shared_resource = 0; sem_t resource_mutex, read_mutex; int num_readers = 0; void *reader(void *arg) { while (1) { sem_wait(&read_mutex); num_readers++; if (num_readers == 1) { sem_wait(&resource_mutex); } sem_post(&read_mutex); printf("Reader read value %d\n", shared_resource); sleep(rand() % 3); sem_wait(&read_mutex); num_readers--; if (num_readers == 0) { sem_post(&resource_mutex); } sem_post(&read_mutex); } } void *writer(void *arg) { while (1) { sem_wait(&resource_mutex); printf("Writer wrote value %d\n", ++shared_resource); sleep(rand() % 3); sem_post(&resource_mutex); } } int main() { pthread_t readers[NUM_READERS], writers[NUM_WRITERS]; sem_init(&resource_mutex, 0, 1); sem_init(&read_mutex, 0, 1); for (int i = 0; i < NUM_READERS; i++) { pthread_create(&readers[i], NULL, reader, NULL); } for (int i = 0; i < NUM_WRITERS; i++) { pthread_create(&writers[i], NULL, writer, NULL); } for (int i = 0; i < NUM_READERS; i++) { pthread_join(readers[i], NULL); } for (int i = 0; i < NUM_WRITERS; i++) { pthread_join(writers[i], NULL); } sem_destroy(&resource_mutex); sem_destroy(&read_mutex); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值