1. 程式人生 > >執行緒——生產者與消費者2.0

執行緒——生產者與消費者2.0

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>

// 定義結構體變數
struct _data
{
	char *buf[10];
	sem_t full; 
	sem_t empty;
	int count;
}data;

// 初始化互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 生產者工作函式
void *producer(void *v)
{
	char *buf[] = {"蘋果", "梨", "波羅蜜", "山竹"};
	int len = sizeof(buf) / sizeof(buf[0]);
	
	while(1)
	{
		usleep(100000*(rand()%10+1));
		
		// 如果訊號量的值為0,就等待
		// 然後減1
		// 初始化為10
		sem_wait(&data.empty);
		pthread_mutex_lock(&mutex);
		
		data.buf[data.count] = buf[rand()%len];
		data.count++;
		
		pthread_mutex_unlock(&mutex);
		sem_post(&data.full);
	}
}

// 消費者
void *customer (void *v)
{
	long num = (long)v;
	
	while(1)
	{
		usleep(100000*(rand()%10+1));
		
		// 如果訊號量的值為0,就等待
		// 然後減1
		// 初始化為0
		// 生產者生產後,該訊號量加了1,此時消費者可以吃了
		sem_wait(&data.full);
		pthread_mutex_lock(&mutex);
		
		int index = rand()%data.count;
		printf ("%ld 消費者吃了一個 %s,剩餘個數%d\n", num, data.buf[index], data.count-1);
		data.count--;
		
		char *tmp = data.buf[data.count];
		data.buf[data.count] = data.buf[index];
		data.buf[index] = tmp;
		
		pthread_mutex_unlock(&mutex);
		sem_post(&data.empty);
	}
}

// 生產者與消費者
int main()
{
	srand((unsigned int)time(NULL));
	
	pthread_t thread;
	
	long i;
	
	for (i = 0; i < 4; i++)
	{
		pthread_create(&thread, NULL, customer, (void *)(i+1));
		pthread_detach(thread);
	}
	
	for (i = 0; i < 4; i++)
	{
		pthread_create(&thread, NULL, producer, NULL);
		pthread_detach(thread);
	}
	
	sem_init(&data.full, 0, 0);
	sem_init(&data.empty, 0, 10);
	
	pthread_exit(NULL);
	
	return 0;
}