nefu操作系统实验3 线程通信

这篇文章描述了一个使用C语言实现的并发控制场景,通过小和尚和大和尚线程填充和倒空水缸来模拟多线程间的协作,利用信号量和互斥锁进行同步。
摘要由CSDN通过智能技术生成

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

#define MAX_WATER_BUCKET 5      // 水桶个数
#define MAX_WATER_CAN 30        // 水缸容量

int water_can = 0;              // 当前水缸中的水量

sem_t fill_sem;                 // 用于小和尚填充水桶的信号量
sem_t empty_sem;                // 用于大和尚倒空水桶的信号量
pthread_mutex_t mutex;          // 互斥锁,用于保护对水缸的访问

void *small_monk_func(void *arg)
{
    while (1) {
        sem_wait(&fill_sem);     // 等待可以填充水桶的信号量

        pthread_mutex_lock(&mutex);
        if (water_can >= MAX_WATER_CAN) {
            printf("The water can is full. Buckets in can: %d\n", water_can);
        } else {
            water_can++;         // 填充水缸
            printf("Small monk filled a bucket of water into the can. Buckets in can: %d\n", water_can);
        }
        pthread_mutex_unlock(&mutex);

        sem_post(&empty_sem);    // 通知大和尚可以倒空水桶
    }
}

void *head_monk_func(void *arg)
{
    while (1) {
        sem_wait(&empty_sem);    // 等待可以倒空水桶的信号量

        pthread_mutex_lock(&mutex);
        if (water_can <= 0) {
            printf("The water can is empty. Buckets in can: %d\n", water_can);
        } else {
            water_can--;         // 倒空水缸
            printf("Head monk emptied a bucket of water from the can. Buckets in can: %d\n", water_can);
        }
        pthread_mutex_unlock(&mutex);

        sem_post(&fill_sem);     // 通知小和尚可以填充水桶
    }
}

int main() {
    pthread_t small_monks[MAX_WATER_CAN];      // 小和尚线程数组
    pthread_t head_monk;

    sem_init(&fill_sem, 0, MAX_WATER_CAN);     // 初始化填充信号量,初始值为最大个数
    sem_init(&empty_sem, 0, 0);                   // 初始化倒空信号量,初始值为0

    pthread_mutex_init(&mutex, NULL);             // 初始化互斥锁

    int i;
    for (i = 0; i < rand()%30+1 i++) {
        pthread_create(&small_monks[i], NULL, small_monk_func, NULL);   // 创建小和尚线程
    }

    pthread_create(&head_monk, NULL, head_monk_func, NULL);              // 创建大和尚线程

    for (i = 0; i < rand()%30+1; i++) {
        pthread_join(small_monks[i], NULL);       // 等待小和尚线程结束
    }

    pthread_join(head_monk, NULL);                // 等待大和尚线程结束

    sem_destroy(&fill_sem);                       // 销毁填充信号量
    sem_destroy(&empty_sem);                      // 销毁倒空信号量

    pthread_mutex_destroy(&mutex);                 // 销毁互斥锁

    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值