标签:des blog http os io 使用 ar 数据 2014
linux中的信号量既可以用于线程间的同步又可以用于进程间的同步。
信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。在公共资源增加的时候,信号两的值增加;公共资源消耗的时候,信号量的值减少;只有当信号量的值大于大于0的时候,才能访问信号量所带表的公共资源。
ps:信号量在linux有posix接口和系统api接口,后者实在是太难记住,所以直接使用前者吧。
有关信号量的主要函数有信号量初始化函数sem_init(3)、信号量的销毁函数sem_destroy(1)、信号量的增加函数sem_post(1)以及信号量的减少函数sem_wait(1)。
信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
int sem_init(sem_t *sem, int pshared, unsigned int value);
   参数
		    sem 指针,指向匿名信号量;
		    value 参数指定信号量的初始值;
		    pshared 参数指明信号量是由进程内线程共享:0是线程共享,非0是进程共享;
	  返回值
		    sem_init() 成功时返回 0;错误时,返回 -1,并把 errno 设置为合适的值。
sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的。
int sem_post(sem_t *sem);
  参数
		    sem 指针,指向匿名信号量;
	  返回值
	    sem_post() 成功时返回 0;错误时,信号量的值没有更改,-1 被返回,并设置 errno 来指明错误。
sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。
	也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,这信号量的值将减到1。
	如果对一个值为0的信号量调用sem_wait(),这个函数就 会地等待直到有其它线程增加了这个值使它不再是0为止。
int sem_wait(sem_t * sem);
   参数
		    sem 指针,指向匿名信号量;
	  返回值
		    sem_wait() 成功时返回 0;错误时,返回 -1,并把 errno 设置为合适的值。
int sem_destroy(sem_t *sem);
   参数
		    sem 指针,指向匿名信号量;
	  返回值
		    sem_wait() 成功时返回 0;错误时,返回 -1,并把 errno 设置为合适的值。

/*
	生产者消费者
	我的例子中有2个消费者,2个生产者,10个缓冲区来存放产品
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define buf_count 10
#define consumer_count 2
#define producer_count 2
int pos;
int cpos;
int buf[buf_count];
pthread_mutex_t buf_mutex,cbuf_mutex;
sem_t buf_empty,buf_full;
void* producer(void *arg)
{
	
	int start = *(int*)arg;
	int end = start + 10;
	while(start < end)
	{
		sem_wait(&buf_empty);
		pthread_mutex_lock(&buf_mutex);
		buf[pos] = start;
		printf("producer%u put buf[%d]:%d\n",pthread_self(),pos,buf[pos]);
		pos = (pos+1)%buf_count;
		pthread_mutex_unlock(&buf_mutex);
		sem_post(&buf_full);
		usleep(1);
		++start;
	}
}
void* consumer(void *arg)
{
	
	while(1)
	{
		sem_wait(&buf_full);
		pthread_mutex_lock(&cbuf_mutex);
		printf("\t consumer%u take buf[%d]:%d\n",pthread_self(),cpos,buf[cpos]);
		pthread_mutex_unlock(&cbuf_mutex);
		cpos = (cpos+1)%buf_count;
		usleep(50);
		sem_post(&buf_empty);
	}
}
int main()
{
	sem_init(&buf_full,0,0);
	sem_init(&buf_empty,0,10);
	pthread_mutex_init(&buf_mutex,NULL);
	pthread_mutex_init(&cbuf_mutex,NULL);
	
	pthread_t consumers[consumer_count];
	pthread_t producers[producer_count];
	
	int producerStart[producer_count];
	int pc = 0;
	while(pc < producer_count)
	{
		producerStart[pc] = pc * 10;
		++pc;
	}
	int i = 0;
	while(i < producer_count)
	{
		printf("main create producer%d\n",i);
		pthread_create(&producers[i],NULL,producer,(void*)&producerStart[i]);
		++i;
	}
	i = 0;
	while(i < consumer_count)
	{
		printf("main create consumer%d\n",i);
		pthread_create(&consumers[i],NULL,consumer,NULL);
		++i;
	}
	i = 0;
	while(i < producer_count)
	{
		pthread_join(producers[i],NULL);
		++i;
	}
	i = 0;
	while(i < consumer_count)
	{
		pthread_join(consumers[i],NULL);
		++i;
	}
	
	pthread_mutex_destroy(&buf_mutex);
	pthread_mutex_destroy(&cbuf_mutex);
	sem_destroy(&buf_full);
	sem_destroy(&buf_empty);
	return 0;
}
标签:des blog http os io 使用 ar 数据 2014
原文地址:http://www.cnblogs.com/dy-techblog/p/3962454.html