您的位置:首页 > 运维架构 > Linux

linux下线程同步

2015-07-22 16:36 417 查看
这里我做的测试使用的模型是生产者消费者模型,分成两种情况

其一只有一个缓冲区,我们使用信号量即可,分成两个,empty 和full。当缓冲区有空时,则生产者生产,当缓冲区full时。消费者消费

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>
//生产者消费者模式,只有一个缓冲区,一个消费者一个生产者
//使用信号量进行线程同步
void* consumer(void* arg);
void* producer(void* arg);
int gBuffer=0;
sem_t empty={0};
sem_t full={0};
int main()
{
	pthread_t c_th={0};
	pthread_t p_th={0};
	int c_res=0;
	int p_res=0;
	sem_init(&empty,0,1);
	sem_init(&full,0,0);
	c_res=pthread_create(&c_th,NULL,consumer,(void*)&gBuffer);
	if(0!=c_res)
	{
		printf("消费者线程创建失败\n");
		exit(0);
	}
	p_res=pthread_create(&p_th,NULL,producer,(void*)&gBuffer);
	if(0!=p_res)
	{
		printf("生产者线程创建失败\n");	
		exit(0);
	}
	void* c_rtl=NULL;
	c_res=pthread_join(c_th,&c_rtl);
	if(0!=c_res)
	{
		printf("消费者线程 pthread_join 失败\n");
		exit(0);
	}
	void* p_rtl=NULL;
	p_res=pthread_join(p_th,&p_rtl);
	if(0!=p_res)
	{	
		printf("生产者 pthread_join 失败\n");
		exit(0);
	}
	sem_destroy(&full);
	sem_destroy(&empty);
	return 0;
}
void * consumer(void* arg)
{
	int nCount=0;
	while(1)
	{
		sem_wait(&full);
		printf("consumer 成功\n");
		sem_post(&empty);
		nCount++;
		if(50==nCount)
			break;
	}
	pthread_exit(0);
}
void * producer(void* arg)
{
	int nCount=0;
	while(1)
	{
		sem_wait(&empty);
		printf("producer 成功\n");
		sem_post(&full);
		nCount++;
		if(50==nCount)
			break;
	}
	pthread_exit(0);
}


当存在多个缓冲区的时候,则除却信号量标记,缓冲区状态的时候,还要为每个缓冲区分配互斥变量,同一时刻,一个缓冲区只能被一个线程访问,无论是生产者还是消费者

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>
//生产者消费者模式,多个缓冲区,多个生产者
//使用信号量进行线程同步
void* consumer(void* arg);
void* producer(void* arg);
int gBuffer[4]={0};
int buf_count=4;
//为每个缓冲区都准备一个互斥变量,同一时间只能有一个线程进行访问
pthread_mutex_t mutex[4]={0};
sem_t empty={0};
sem_t full={0};
int main()
{
	pthread_t c_th={0};
	pthread_t p_th={0};
	int c_res=0;
	int p_res=0;
	sem_init(&empty,0,4);
	sem_init(&full,0,0);
	int i=0;
	for(;i<buf_count;i++)
	{
		pthread_mutex_init(&mutex[i],NULL);
	}
	c_res=pthread_create(&c_th,NULL,consumer,(void*)&gBuffer);
	if(0!=c_res)
	{
		printf("消费者线程创建失败\n");
		exit(0);
	}
	p_res=pthread_create(&p_th,NULL,producer,(void*)&gBuffer);
	if(0!=p_res)
	{
		printf("生产者线程创建失败\n");	
		exit(0);
	}
	void* c_rtl=NULL;
	c_res=pthread_join(c_th,&c_rtl);
	if(0!=c_res)
	{
		printf("消费者线程 pthread_join 失败\n");
		exit(0);
	}
	void* p_rtl=NULL;
	p_res=pthread_join(p_th,&p_rtl);
	if(0!=p_res)
	{	
		printf("生产者 pthread_join 失败\n");
		exit(0);
	}
	sem_destroy(&full);
	sem_destroy(&empty);
	for(i=0;i<buf_count;i++)
	{
		pthread_mutex_destroy(&mutex[i]);
	}
	return 0;
}
void * consumer(void* arg)
{
	int nCount=0;
	int i=0;
	while(nCount<=20)
	{
		sem_wait(&full);
		for(i=0;i<buf_count;i++)			
		{
			if(1==gBuffer[i])
			{
				pthread_mutex_lock(&mutex[i]);
				gBuffer[i]=0;
				printf("缓冲区%d归0\n",i);		
				pthread_mutex_unlock(&mutex[i]);
				sem_post(&empty);
				nCount++;
			}
		}
	}
	pthread_exit(0);
}
void * producer(void* arg)
{
	int nCount=0;
	int i=0;
	while(nCount<=20)
	{
		sem_wait(&empty);
		for(i=0;i<buf_count;i++)
		{
			if(gBuffer[i]==0)
				{
					pthread_mutex_lock(&mutex[i]);
					gBuffer[i]=1;
					printf("缓冲区%d置位\n",i);
					pthread_mutex_unlock(&mutex[i]);
					sem_post(&full);
					nCount++;
				}
		}		
	}
	pthread_exit(0);
}


跟上一篇一样,说下 makefile的内容,多了一个 -lrt

test: thread.o
	gcc -o test thread.o  -lpthread  -lrt
thread.o:thread.c
	gcc -c thread.c
clean:
	rm test *.o
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: