pthread-消费者/生产者模型实现

pthread-消费者/生产者模型实现

消费者/生产者模型是多线程编程开发的常用模型,该模型通过平衡生产者线程和消费者线程的工作能力来提高程序整体的数据处理能力。
设计该模型要注意以下几项:
- 资源池一般是有限的,访问资源是要加锁,访问完毕时记得解锁
- 生产者需要在资源池未满的情况下才能生产产品
- 消费者需要在资源池不空的情况下才能消费产品
- 设计时应考虑如何避免死锁问题
下面的例子是采用 semaphore,资源池为环形缓冲区,来实现消费者/生产者模型。代码如下:

#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERROR(func, no) { \
        fprintf(stderr, "%s: %s\n", func, strerror(no)); \
        exit(EXIT_FAILURE); \
    }

#define DEFAULT_CONSUMER_CNT    1
#define DEFAULT_PRODUCER_CNT    3
#define DEFAULT_BUFFER_SIZE 10


static size_t in; //  producer's current pos
static size_t out; // consumer's current pos
static size_t consumer_id; // current product id for consumer 
static size_t producer_id; // current product id for producer
static size_t consumer_cnt; // count of consumers
static size_t producer_cnt; // count of producers
static size_t buff_size; // resource buffer size

static int* g_buffer = NULL; // pointer to resource buffer
static pthread_t* g_thread = NULL; // pointer to thread IDs

static pthread_mutex_t g_mutex; //mutex
static sem_t* g_sem_empty_ptr = NULL; // semaphore for consumer
static sem_t* g_sem_full_ptr = NULL; // semaphore for producer

void* consume(void* arg) {
    int id = *(int*)arg;
    free(arg);

    while(1) {
        
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者消费者模型是计算机科学中一个经典的问题,也是进程同步与互斥的一个重要应用。该模型描述了一个生产者和一个消费者共同使用一个有限缓冲区的情景,生产者向缓冲区中添加数据,而消费者则从缓冲区中取出数据。 为了避免在共享缓冲区时产生数据不一致的情况,需要进行进程同步和互斥。其中,进程同步是指在多个进程之间协调事件发生的时间,而互斥则是指在同一时间只允许一个进程访问共享资源。 以下是一个基于信号量的生产者消费者模型的示例: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; // 缓冲区 int in = 0; // 生产者写入数据的位置 int out = 0; // 消费者读取数据的位置 sem_t empty; // 信号量,表示缓冲区中空余的位置数 sem_t full; // 信号量,表示缓冲区中已有数据的位置数 sem_t mutex; // 信号量,用于实现互斥访问缓冲区 void *producer(void *arg) { int item; while(1) { item = rand() % 1000; // 生产者随机生成一个数据项 sem_wait(&empty); // 等待缓冲区有空余位置 sem_wait(&mutex); // 进入互斥区,保证对缓冲区的访问是互斥的 buffer[in] = item; printf("Producer produces item %d at buffer[%d]\n", item, in); in = (in + 1) % BUFFER_SIZE; sem_post(&mutex); // 退出互斥区 sem_post(&full); // 增加已有数据的位置数 sleep(rand() % 2); // 生产者随机休眠一段时间 } } void *consumer(void *arg) { int item; while(1) { sem_wait(&full); // 等待缓冲区有数据 sem_wait(&mutex); // 进入互斥区 item = buffer[out]; printf("Consumer consumes item %d from buffer[%d]\n", item, out); out = (out + 1) % BUFFER_SIZE; sem_post(&mutex); // 退出互斥区 sem_post(&empty); // 增加空余位置数 sleep(rand() % 2); // 消费者随机休眠一段时间 } } int main() { pthread_t producer_thread, consumer_thread; sem_init(&empty, 0, BUFFER_SIZE); // 初始化信号量 sem_init(&full, 0, 0); sem_init(&mutex, 0, 1); 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); sem_destroy(&mutex); return 0; } ``` 在上述代码中,empty 表示缓冲区中空余的位置数,初始值为 BUFFER_SIZE;full 表示缓冲区中已有数据的位置数,初始值为 0;mutex 用于实现互斥访问缓冲区,初始值为 1。在生产者消费者访问缓冲区时,都需要先进行信号量操作,保证进程同步和互斥。其中,sem_wait 和 sem_post 分别表示等待和增加信号量的值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值