多线程编程——条件变量

本文介绍了一个使用pthread线程库实现的生产者消费者模式示例。通过一个链表作为缓冲区,生产者线程不断向链表头部插入数据,而消费者线程从链表中取出并消费数据。使用了互斥锁和条件变量来同步线程间的访问。

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

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/* 静态方式初始化一个互斥锁和一个条件变量 */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* 指向线程控制块的指针 */
static pthread_t tid1;
static pthread_t tid2;
/* 函数返回值检查 */
static void check_result(char* str,int result)
{
	if (0 == result)
	{
		printf("%s successfully!\n",str);
	}
	else
	{
		printf("%s failed! error code is %d\n",str,result);
	}
}
/* 生产者生产的结构体数据,存放在链表里 */
struct node
{
	int n_number;
	struct node* n_next;
};
struct node* head = NULL; /* 链表头,是共享资源 */
/* 消费者线程入口函数 */
static void* consumer(void* parameter)
{
	struct node* p_node = NULL;
	pthread_mutex_lock(&mutex); /* 对互斥锁上锁 */
	while (1)
	{
		while (head == NULL) /* 判断链表里是否有元素 */
		{
			pthread_cond_wait(&cond,&mutex); /* 尝试获取条件变量 */
		}
		/*
		pthread_cond_wait()会先对mutex解锁,
		然后阻塞在等待队列,直到获取条件变量被唤醒,
		被唤醒后,该线程会再次对mutex上锁,成功进入临界区。
		*/
		p_node = head; /* 拿到资源 */
		head = head->n_next; /* 头指针指向下一个资源 */
		/* 打印输出 */
		printf("consume %d\n",p_node->n_number);
		free(p_node); /* 拿到资源后释放节点占用的内存 */
	}
	pthread_mutex_unlock(&mutex); /* 释放互斥锁 */
	return 0;
}
/* 生产者线程入口函数 */
static void* product(void* patameter)
{
	int count = 0;
	struct node *p_node;
	while(1)
	{
		/* 动态分配一块结构体内存 */
		p_node = (struct node*)malloc(sizeof(struct node));
		if (p_node != NULL)
		{
			p_node->n_number = count++;
			pthread_mutex_lock(&mutex); /* 需要操作head这个临界资源,先加锁 */
			p_node->n_next = head;
			head = p_node; /* 往链表头插入数据 */
			pthread_mutex_unlock(&mutex); /* 解锁 */
			printf("produce %d\n",p_node->n_number);
			pthread_cond_signal(&cond); /* 发信号唤醒一个线程 */
			usleep(2); /* 休眠2微秒 */
		}
		else
		{
			printf("product malloc node failed!\n");
			break;
		}
	}
}
/* 用户应用入口 */
int application_init()
{
	int result;
	/* 创建生产者线程,属性为默认值,入口函数是product,入口函数参数为NULL*/
	result = pthread_create(&tid1,NULL,product,NULL);
	check_result("product thread created ",result);
	/* 创建消费者线程,属性为默认值,入口函数是consumer,入口函数参数是NULL */
	result = pthread_create(&tid2,NULL,consumer,NULL);
	check_result("consumer thread created ",result);
	return 0;
}
int main()
{
	int i ;
	application_init();
	i=100;
	do{
		sleep(1);
	}while(i--);
}

运行结果:

-bash-3.2$ ./app
product thread created successfully!
consumer thread created successfully!
produce 0
consume 0
produce 1
consume 1
produce 2
consume 2
produce 3
consume 3
produce 4
consume 4
produce 5
consume 5
produce 6
consume 6
produce 7
consume 7
produce 8
consume 8
produce 9
consume 9
produce 10
consume 10
produce 11
consume 11
produce 12
consume 12
produce 13
consume 13
produce 14
consume 14
produce 15
consume 15
produce 16
consume 16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值