关于条件变量

最近想自己实现一个线程池,发现线程池的实现主要是条件变量和互斥量的使用,因此先练习了条件变量个互斥锁。这篇文章主要记录学习过程中遇到的问题。

下面是自己写的一个程序,用于练习。

#include "../common.h"     //包含线程所需头文件

pthread_t   pid1, pid2;
pthread_cond_t    num;
pthread_mutex_t   mutex1, mutex2;     //由于有两个线程,使用两个条件变量
int count;    //条件

void *func1(void *argc)
{	
	//pthread_detach(pthread_self());
	printf("thread1 %lu create success!\n", pthread_self());
	printf("1 wait for signal cmd!\n");
	pthread_mutex_lock(&mutex1);
	while(count == 0)
	{
		printf("1count = %d\n", count);
		printf("=============================\n");
		pthread_cond_wait(&num, &mutex1);
	}
	printf("1 reserve signal, i will continue!\n");	
}

void *func2(void *argc)
{	
	//pthread_detach(pthread_self());
	printf("thread2 %lu create success!\n", pthread_self());
	printf("2 wait for signal cmd!\n");
	pthread_mutex_lock(&mutex2);
	while(count == 0)
	{
		printf("2count = %d\n", count);
		printf("=============================\n");
		pthread_cond_wait(&num, &mutex2);
	}
	printf("2 reserve signal, i will continue!\n");	
}

int add()
{
	printf("alls go go go!\n");
	if (count == 0)
	{
		count++;
		pthread_cond_broadcast(&num);
		printf("send signal success!\n");
		
	}
	pthread_mutex_unlock(&mutex1);
	pthread_mutex_unlock(&mutex2);
	return 0;
}

int main(int argc, char **argv)
{
	void **state;
	pthread_mutex_init(&mutex1, NULL);
	pthread_mutex_init(&mutex2, NULL);
	pthread_cond_init(&num, NULL);
	pthread_create(&pid1, NULL, func1, NULL);
	sleep(3);
	pthread_create(&pid2, NULL, func2, NULL);
	sleep(4);
	add();
	pthread_join(pid1, (void*)&state);
	pthread_join(pid2, (void*)&state);
	sleep(3);
	pthread_mutex_destroy(&mutex1);
	pthread_mutex_destroy(&mutex2);
	pthread_cond_destroy(&num);
	printf("main thread exit!\n");
	return 0;
}

这段代码的实现很简单,主要就是创建两个线程分别阻塞,然后等待条件变量成立,发送信号,接触阻塞,线程继续执行。下面是这段代码的一个打印

thread1 77757296 create success!
1 wait for signal cmd!
1count = 0
=============================
thread2 92441456 create success!
2 wait for signal cmd!
2count = 0
=============================
alls go go go!
1 reserve signal, i will continue!
send signal success!
2 reserve signal, i will continue!
main thread exit!

在主函数中添加了sleep延时,方便观察现象,其中的一些问题有这些

  1. 和前面的线程回收资源有关,采用分离线程或者是pthread_join来回收资源,开始由于线程里面的条件变量count的处理问题,导致在线程收到信号后,count还是为1,程序阻塞在pthread_cond_wait处,pthread_join得不到资源,就会阻塞程序,但是使用线程分离的话,程序会正常退出,由于count的原因,最后也会有内存泄漏问题。
  2. 关于pthread_cond_wait、pthread_cond_signal以及pthread_cond_boardcast这三个函数,其中前者用于阻塞线程,但是要配合条件变量count一起使用,后面两个分别用于单个线程和多个线程,count的自增操作一定要在发送信号之前,不然wait的时候count还是为0,导致接触阻塞失败。
  3. 关于互斥量,用于多个线程阻塞的时候,其实在每个线程执行里面,可共享一把锁,得到的结果是一样的,因为pthread_cond_wait函数在阻塞的时候会打开锁,所以两一个线程变可以得到这把锁,当返回的时候又会再次锁住互斥锁,因此这里不会出现死锁问题。

分析得很浅显,有哪些错误希望大家指正。

你可能感兴趣的:(APUE,条件变量)