欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程同步之条件变量 生产者和消费者模型

程序员文章站 2024-03-18 12:17:40
...

条件变量

注意:需与互斥量一起使用,实现线程以互斥方式阻塞等待特定条件的发生(同步)

使用步骤

  1. 定义条件变量
  2. 初始化条件变量,初始化互斥量
  3. 触发条件线程x:互斥量加锁->XX操作->触发条件变量->互斥量解锁
  4. 循环等待条件线程y:互斥量加锁->等待条件变量->XX操作->互斥量解锁。
    注意:这里循环等待是避免等待线程由其他信号打断后被唤醒,需重新判断cond值。
  5. 销毁条件变量与互斥量变量

API函数

  1. 初始化
    静态:pthread_cond_t cond = PTHREAD_COND_INITIALIZER
    动态:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr)
    参数1cond:条件变量
    参数2attr:条件变量属性,若为NULL,则默认属性
    成功返回0,失败返回错误码

  2. 销毁
    Int pthread_cond_destroy(pthread_cond_t *cond)
    参数为条件变量,成功返回0,失败返回错误码

  3. 等待条件变量与计时等待
    Int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
    int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
    参数1cond:条件变量
    参数2mutex:互斥量
    成功0,失败错误码(参数不正确)

  4. 触发条件变量唤醒等待线程队列中的某一个线程
    Int pthread_cond_signal(pthread_cond_t *cond)
    成功0,失败错误码

  5. 触发条件变量唤醒等待线程队列中的所有线程,这些线程会进行竞争
    Int pthread_cond_broadcast(pthread_cond_t *cond)
    成功0,失败错误码

功能实现:进程中创建两个线程,线程A作为生产者循环不断生成数据,将数据加入单链表中,线程B作为消费者循环不断获取数据,并将该数据从链表中删除且释放空间。其中链表作为全部变量,以供两个线程操作。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//单链表模型
struct msg{
	struct msg *next;
	int num;
};
//表头
struct msg head = {
	.next = NULL,
	.num = 0,
};
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)
{
	struct msg *mp;
	for(;;){
		pthread_mutex_lock(&lock);
		while(head.next == NULL)
			pthread_cond_wait(&has_product, &lock);
		mp = head.next;//从头部获取
		head.next = mp->next;
		pthread_mutex_unlock(&lock);
		printf("Consume %d\n",mp->num);
		free(mp);
		sleep(rand()%5);
	}
}

void *producer(void *p)
{
	struct msg *mp,*pre;
		pre = NULL;
	for(;;){
		//生成新结点
		mp = malloc(sizeof(struct msg));
		mp->num = rand() % 1000 + 1;//随机获取一个三位数的数据
		mp->next = pre;
		printf("Produce %d\n", mp->num);
		pthread_mutex_lock(&lock);
		head.next = mp;//采用头插法
		pthread_cond_signal(&has_product);
		pthread_mutex_unlock(&lock);
		pre = mp;
		sleep(rand() % 5);
	}
}

int main(void)
{
	pthread_t pid,cid;
	//set the random arg
	srand(time(NULL));
	pthread_create(&pid, NULL, producer, NULL);
	pthread_create(&cid, NULL, consumer, NULL);
	pthread_join(pid,NULL);
	pthread_join(cid,NULL);
	return 0;
}
验证结果:
Produce 230
Produce 720
Consume 720
Consume 230
Produce 582
。。。
相关标签: 条件变量