多线程编程——条件变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31860135/article/details/84957868
#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

猜你喜欢

转载自blog.csdn.net/qq_31860135/article/details/84957868
今日推荐