Linux环境编程之同步(二):条件变量

相互排斥锁用于上锁,条件变量则用于等待。条件变量是类型为pthread_cond_t的变量。一般使用例如以下函数:

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
每一个条件变量总是有一个相互排斥锁与之关联。调用pthread_cond_wait等待某个条件为真时,还会指定其条件变量的地址和所关联的相互排斥锁的地址。

使用条件变量的生产者-消费者程序例如以下:

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

#define MAXNITEMS	1000000
#define MAXNTHREADS		100

/*globals shared by threads*/
int 	nitems;		/*read-only by producer and consumer*/
int		buff[MAXNITEMS];
struct{
	pthread_mutex_t	mutex;
	int				nput;	/*next index to store*/
	int 			nval;	/*next value to store*/
}put = {
	PTHREAD_MUTEX_INITIALIZER
};

struct{
	pthread_mutex_t mutex;
	pthread_cond_t	cond;
	int				nready;	/*number ready for consumer*/
}nready={
	PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER
};

int min(int a, int b)
{
	return (a < b) ? (a) : (b);
}

void *produce(void *), *consume(void *);

int
main(int argc, char **argv)
{
	int 	i, nthreads, count[MAXNTHREADS];
	pthread_t	tid_produce[MAXNTHREADS], tid_consume;

	if(argc != 3){
		printf("usage:produces6 <#items> <#threads>.
");
		return -1;
	}
	nitems = min(atoi(argv[1]), MAXNITEMS);
	nthreads = min(atoi(argv[2]), MAXNTHREADS);

	/*create all producers and one consumer*/
	pthread_setconcurrency(nthreads + 1);
	for(i = 0; i < nthreads; i++){
		count[i] = 0;
		pthread_create(&tid_produce[i], NULL, produce, &count[i]);	
	}
	pthread_create(&tid_consume, NULL, consume, NULL);


	/*wait for all producers and the consumer*/
	for(i = 0; i < nthreads; i++){
		pthread_join(tid_produce[i], NULL);	
		printf("count[%d] = %d
", i, count[i]);
	}
	pthread_join(tid_consume, NULL);

	exit(0);
}

void *
produce(void *arg)
{
	for(;;){
		pthread_mutex_lock(&put.mutex);	
		if(put.nput >= nitems){
			pthread_mutex_unlock(&put.mutex);	
			return (NULL);		/*array is full, we're done*/
		}
		buff[put.nput] = put.nval;
		put.nput++;
		put.nval++;
		pthread_mutex_unlock(&put.mutex);

		pthread_mutex_lock(&nready.mutex);
		if(nready.nready == 0){
			pthread_cond_signal(&nready.cond);	
		}
		nready.nready++;
		pthread_mutex_unlock(&nready.mutex);

		*((int *)arg) += 1;
	}
}

void *
consume(void *arg)
{
	int		i;
	for(i = 0; i < nitems; i++){
		pthread_mutex_lock(&nready.mutex);
		while(nready.nready == 0)
			pthread_cond_wait(&nready.cond, &nready.mutex);
		nready.nready--;
		pthread_mutex_unlock(&nready.mutex);	

		if(buff[i] != i)
			printf("buff[%d] = %d
", i, buff[i]);
	}
	return(NULL);
}



原文地址:https://www.cnblogs.com/zfyouxi/p/4268171.html