本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
Intro
- 本文为多生产者多消费者的C语言实现
- 生产者与消费者针对链表的头结点进行操作
- 使用的现场同步方法为信号量
- 本文侧重于理解条件变量的使用
- 为保证代码简洁,本文代码没有对函数的返回值进行检查,聪明的你一定一定知道如何检查这个小细节(•̀ᴗ•́)و ̑̑
- 关于互斥锁+条件变量的多生产者多消费者模型实现请参考我的这篇博客
analysis
多生产者多消费者有多个线程,当根据信号量定义的资源数不同,所对应的情况也有所不同,所以在使用信号量去实现多生产者多消费者模型要处理好资源数与多线程之间的关系,在拥有多个资源数时可以配合互斥锁来约束多线程对共享资源的访问
单生产者单消费者
- 限于篇幅,本篇博客仅简单提及此模型,不展示具体代码
- 对于单生产者单消费者,资源数只能为1,每次唤醒一个线程,情况并不复杂
- 若资源数大于1,实际运行就会产生段错误(读写了不该访问的地址)
多生产者多消费者
资源数为1
sem_init(&psem, 0, 1);//意义为初始化生产者信号量,用于处理线程,资源数为1
sem_init(&csem, 0, 0);//意义为初始化消费者信号量,用于处理线程,资源数为0
如此定义的好处为:
-
使生产者先工作
-
由于资源数为1,程序运行中只有一个线程可被唤醒,不会出现多个线程同时访问共享资源的的情况
-
无需添加互斥锁对共享资源进行保护
-
SHOW ME THE CODE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
struct Node {
int number;
struct Node *next;
};
struct Node *head = NULL;
sem_t psem;//生产者信号量
sem_t csem;//消费者信号量
void *producer(void *arg);//生产者函数
void *consumer(void *arg);//消费者函数
int main(int argc, char **argv)
{
pthread_t ptid[5];//生产者线程
pthread_t ctid[5];//消费者线程
sem_init(&psem, 0, 1);//初始化生产者信号量,生产者线程拥有1个信号灯
sem_init(&csem, 0, 0);//初始化消费者信号量,消费者线程拥有0个信号灯
//如此这般的意义是使生产者线程先运行
for(int i = 0; i <