zoukankan      html  css  js  c++  java
  • 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);
    }



  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4268171.html
Copyright © 2011-2022 走看看