条件变量加互斥锁实现生产者——消费者模型(C语言)

1. 什么是条件变量?

  • 通俗的讲就是当满足某个条件的时候我们就让程序干我们想干的活,条件不满足那就让它阻塞,等到条件满足为止。

2. 什么是互斥锁?

  • 互斥锁其实就是用来保护共享资源的一种锁,当多个线程访问共享资源的时候(比如全局数据,堆区开辟的空间)就需要使用互斥锁,才能达到线程同步的效果,这里的同步不是指一起,相同,而是协同的意思,是有先后顺序的。

条件变量函数调用:

  1. 条件变量初始化函数
 int pthread_cond_init(pthread_cond_t *restrict cond,
           const pthread_condattr_t *restrict attr);
  1. 信号发射函数
int pthread_cond_signal(pthread_cond_t *cond);
  1. 阻塞函数
 int pthread_cond_wait(pthread_cond_t *restrict cond,
           pthread_mutex_t *restrict mutex);

互斥锁函数调用:

  1. 互斥锁初始化函数
 int pthread_mutex_init(pthread_mutex_t *restrict mutex,
           const pthread_mutexattr_t *restrict attr);
  1. 互斥锁上锁函数
 int pthread_mutex_lock(pthread_mutex_t *mutex);
  1. 互斥锁解锁函数
 int pthread_mutex_unlock(pthread_mutex_t *mutex);

介绍完基本概念我们就来看看怎么实现生产者——消费者模型

场景是这样子的:

一个线程不断生产新数据,另一个线程则消费生产出来的数据,比喻成做汉堡,顾客去店里买汉堡。买汉堡肯定要等吧,人多了就更要排队了,所以就必须等到汉堡做出来才能买上,这就是一个生产者,消费者模型。

用代码实现就是首先创建两个线程,一个负责生产,一个负责消费。如果没有生产出来那么就要让消费者等,直到生产出东西来。

demo:

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

int g_var = 0;

pthread_mutex_t mutex;
pthread_cond_t cond;


//链表节点
typedef struct node
{
		int data;
		struct node* next;
}Node;

//链表头结点
Node* head = NULL;

void* producer(void* arg)
{
		int count = 100;
		while(count--)
		{
				Node* pnew = (Node*)malloc(sizeof(Node));
				pthread_mutex_lock(&mutex);
				pnew->data = rand()%1000;
				printf("producer thread  %lu, data  %d\n",pthread_self(),pnew->data);
				pnew->next = head;
				head = pnew;
				pthread_cond_signal(&cond);
				pthread_mutex_unlock(&mutex);
				usleep(rand()%100);
		}

		pthread_exit(NULL);
}


void* customer(void* arg)
{
		int count = 100;
		while(count--)
		{
				pthread_mutex_lock(&mutex);
				if(head == NULL)
				{
						pthread_cond_wait(&cond,&mutex);
				}
				
				//消费
				printf("customer thread  %lu, data  %d\n",pthread_self(),head->data);
				Node* pcur = head;
				head = head->next;
				free(pcur);
				pthread_mutex_unlock(&mutex);
				usleep(rand()&100);
		}

		pthread_exit(NULL);
}

int main()
{
		//播种
		srand(time(NULL));

		pthread_t pthid[2];

		//初始化互斥锁
		pthread_mutex_init(&mutex,NULL);
				
		//初始化条件变量
		pthread_cond_init(&cond,NULL);

		//创建生产者线程
		pthread_create(&pthid[0],NULL,producer,NULL);
		//创建消费者线程
		pthread_create(&pthid[1],NULL,customer,NULL);
		
		//回收两个线程
		pthread_join(pthid[0],NULL);
		pthread_join(pthid[1],NULL);

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

		//销毁条件变量
		pthread_cond_destroy(&cond);
		
		pthread_exit(NULL);
}	

运行结果:

在这里插入图片描述如果有兴趣的可以尝试写写生产者和多个消费者的场景

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中,可以使用C语言条件变量和线程来实现消费者-生产者模型。下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_prod = PTHREAD_COND_INITIALIZER; pthread_cond_t cond_cons = PTHREAD_COND_INITIALIZER; void *producer(void *arg) { int item = 0; while (1) { pthread_mutex_lock(&mutex); // 如果缓冲区已满,则等待消费者消费 while (count == BUFFER_SIZE) { pthread_cond_wait(&cond_prod, &mutex); } buffer[count] = item; count++; printf("Producer produced item %d\n", item); // 唤醒消费者线程 pthread_cond_signal(&cond_cons); pthread_mutex_unlock(&mutex); item++; } pthread_exit(NULL); } void *consumer(void *arg) { while (1) { pthread_mutex_lock(&mutex); // 如果缓冲区为空,则等待生产者生产 while (count == 0) { pthread_cond_wait(&cond_cons, &mutex); } int item = buffer[count - 1]; count--; printf("Consumer consumed item %d\n", item); // 唤醒生产者线程 pthread_cond_signal(&cond_prod); pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main() { 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); return 0; } ``` 在上面的代码中,生产者线程不断地向缓冲区中生产数据,而消费者线程不断地从缓冲区中消费数据。当缓冲区满时,生产者线程会等待条件变量`cond_prod`,直到有消费者消费数据才会被唤醒。同样,当缓冲区为空时,消费者线程会等待条件变量`cond_cons`,直到有生产者生产数据才会被唤醒。 需要注意的是,在生产者消费者线程之间共享的变量`count`和`buffer`需要进行互斥访问,因此使用了互斥锁`mutex`来保护共享资源的访问。 希望这个示例能帮助你理解如何在Linux中使用C语言条件变量和线程实现消费者-生产者模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值