下面是基于信号量和互斥锁的生产者消费者模型:
#include<pthread.h> #include<unistd.h> #include<stdio.h> #include<sys/types.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<semaphore.h> #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> #define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while(0) #define CONSUMER_COUNT 2 #define PRODUCER_COUNT 5 #define BUFFSIZE 10 int g_buffer[BUFFSIZE]; unsigned int in=0; unsigned int out=0; unsigned product_id=0; unsigned consumer_id=0; sem_t g_sem_full; sem_t g_sem_empty; pthread_mutex_t g_mutex; pthread_t g_thread[CONSUMER_COUNT+PRODUCER_COUNT]; void* consume(void *arg) { int n=(int)((long)arg); while(1) { printf("%d consumer is waiting\n",n); sem_wait(&g_sem_empty); pthread_mutex_lock(&g_mutex); for(int i=0;i<BUFFSIZE;i++) { printf("%d ",i); printf("%d ",g_buffer[i]); if(i==out)printf("\t<--consume"); printf("\n"); } printf("out=%d\n",out); consumer_id=g_buffer[out]; printf("%d thread %d is consumer %d\n",n,(int)pthread_self(),consumer_id); g_buffer[out]=-1; out=(out+1)%BUFFSIZE; printf("end consumer %d\n",consumer_id); pthread_mutex_unlock(&g_mutex); sem_post(&g_sem_full); sleep(1); } return NULL; } void* produce(void *arg) { int n=(int)((long)arg); while(1) { printf("%d produce is waiting\n",n); sem_wait(&g_sem_full); pthread_mutex_lock(&g_mutex); for(int i=0;i<BUFFSIZE;i++) { printf("%d ",i); printf("%d",g_buffer[i]); if(in==i)printf("\t-->produce"); printf("\n"); } printf("in=%d\n",in); printf("%d thread %d is product %d\n",n,(int)pthread_self(),product_id); g_buffer[in]=product_id; in=(in+1)%BUFFSIZE; printf("end produce product %d\n",product_id++); pthread_mutex_unlock(&g_mutex); sem_post(&g_sem_empty); sleep(5); } } int main() { for(int i=0;i<BUFFSIZE;i++)g_buffer[i]=-1; sem_init(&g_sem_full,0,BUFFSIZE) ; sem_init(&g_sem_empty,0,0); pthread_mutex_init(&g_mutex,NULL); int i=0; for(i=0;i<CONSUMER_COUNT;i++) { pthread_create(&g_thread[i],NULL,consume,(void*)((long) i)); } for(i=0;i<PRODUCER_COUNT;i++) { pthread_create(&g_thread[i+CONSUMER_COUNT],NULL,produce,(void*)((long) i)); } for(i=0;i<CONSUMER_COUNT+PRODUCER_COUNT;i++)pthread_join(g_thread[i],NULL); sem_destroy(&g_sem_full); sem_destroy(&g_sem_empty); pthread_mutex_destroy(&g_mutex); }