使用信号量解决生产者、计算者、消费者问题功能和前面的实验相同,使用信号量解决

本文展示了如何使用C语言实现一个多线程程序,涉及到缓冲区操作、信号量和互斥锁的概念。程序中包含生产者、消费者和计数器线程,它们通过共享缓冲区进行通信,并利用信号量进行同步,确保了数据的一致性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路相同

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

#define CAPACITY 4
int buffer1[CAPACITY];
int buffer2[CAPACITY];
int in1;
int out1;
int in2;
int out2;

int buffer_is_empty1()
{
    return in1 == out1;
}

int buffer_is_full1()
{
    return (in1 + 1) % CAPACITY == out1;
}

int buffer_is_empty2()
{
    return in2 == out2;
}

int buffer_is_full2()
{
    return (in2 + 1) % CAPACITY == out2;
}

int get_item1()
{
    int item;

    item = buffer1[out1];
    out1 = (out1 + 1) % CAPACITY;
    return item;
}

void put_item1(int item)
{
    buffer1[in1] = item;
    in1 = (in1 + 1) % CAPACITY;
}

int get_item2()
{
    int item;

    item = buffer2[out2];
    out2 = (out2 + 1) % CAPACITY;
    return item;
}

void put_item2(int item)
{
    buffer2[in2] = item;
    in2 = (in2 + 1) % CAPACITY;
}
typedef struct {
    int value;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
} sema_t;

void sema_init(sema_t *sema, int value)
{
    sema->value = value;
    pthread_mutex_init(&sema->mutex, NULL);
    pthread_cond_init(&sema->cond, NULL);
}

void sema_wait(sema_t *sema)
{
    pthread_mutex_lock(&sema->mutex);
    while (sema->value <= 0)
        pthread_cond_wait(&sema->cond, &sema->mutex);
    sema->value--;
    pthread_mutex_unlock(&sema->mutex);
}

void sema_signal(sema_t *sema)
{
    pthread_mutex_lock(&sema->mutex);
    ++sema->value;
    pthread_cond_signal(&sema->cond);
    pthread_mutex_unlock(&sema->mutex);
}

sema_t mutex;
sema_t wait_empty_buffer1;
sema_t wait_full_buffer1;
sema_t wait_empty_buffer2;
sema_t wait_full_buffer2;
#define ITEM_COUNT (CAPACITY * 2)
void *consume(void *arg)
{
	 int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
        sema_wait(&wait_full_buffer2);
        sema_wait(&mutex);

        item = get_item2(); 
        printf("%c ",item);
       sema_signal(&mutex);
    	sema_signal(&wait_empty_buffer2);
    }
    return NULL;
} 
void *counter(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
        sema_wait(&wait_full_buffer1);
        sema_wait(&mutex);

        item = get_item1(); 
      // printf("counter1:%c ",item);
        sema_wait(&wait_empty_buffer2);
		item = item - 32;
     // printf("counter2:%c ",item);
        put_item2(item);
		sema_signal(&mutex);
		sema_signal(&wait_full_buffer2);
    	sema_signal(&wait_empty_buffer1);
    }
    return NULL;
}

void *produce(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
    	sema_wait(&wait_empty_buffer1);
        sema_wait(&mutex);
        item = 'a' + i;
       // printf("produce:%c \n",item);
        put_item1(item);
        sema_signal(&wait_full_buffer1);
        sema_signal(&mutex);
    }
    return NULL;
}

int main()
{ 
    pthread_t consumer_tid;
	pthread_t counter_tid;
	sema_init(&mutex, 1);
    sema_init(&wait_empty_buffer1, CAPACITY - 1);
    sema_init(&wait_full_buffer1, 0);
	sema_init(&wait_empty_buffer2, CAPACITY - 1);
    sema_init(&wait_full_buffer2, 0);
    
	pthread_create(&counter_tid, NULL, counter, NULL);
    pthread_create(&consumer_tid, NULL, consume, NULL);
    
    produce(NULL); 
    pthread_join(counter_tid, NULL);
    pthread_join(consumer_tid, NULL);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值