取走产品去消费。尽管所有的生产者线程和消费者线程是以异方式运行,但它们必须保持同步:当一个缓冲区为空时不允许消费者去取走产品,当一个缓冲区满时也不允许生产者去存入产品。
分别定义了两个信号量,empty信号初始值为1,表示buffer缓冲区是空的;full信号量初始化值为0,表示buffer满的标志。
static sem_t buffer_empty_sem; //init value 1,unlock
static sem_t buffer_full_sem; //init value 0,lock
sem_init (&buffer_empty_sem, 0, 1); //unlock
sem_init (&buffer_full_sem, 0, 0); //lock
static char buffer[32];
其中buffer是缓冲区,生产者可以往buffer里面生成数据,消费者可以从buffer里面获取数据,这例子是对数据的打印。
程序流程图:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
static volatile int msg_count = 0;
static char buffer[32];
pthread_mutex_t mutex;
static sem_t buffer_empty_sem; //init value 1,unlock
static sem_t buffer_full_sem; //init value 0,unlock
void ConsumerProducts (char *hex, int size)
{
int i;
char pTmp[32];
char * newchar = NULL;
if(hex ==NULL || size <= 0)
return ;
newchar = (char *)malloc(size*3);
//memset(newchar,0,sizeof(size*3));
strcpy(newchar,"");
for(i=0; i< size; i++)
{
sprintf(pTmp,"%02X", hex[i]);
strcat(newchar, pTmp);
}
//printf("Hex string %s\n",newchar);
printf("consumer ......\n");
if(newchar!=NULL)
{
free(newchar);
newchar = NULL;
}
}
void * producer(void *param)
{
while (1) {
sem_wait( &buffer_empty_sem ); //p
pthread_mutex_lock(&mutex);
msg_count ++ ;
for (int i = 0 ; i < sizeof(buffer); i++)
{
buffer[i] = i ;
}
printf("I am producer msg_count = %d \n",msg_count);
usleep(100 *1000);
pthread_mutex_unlock(&mutex);
sem_post( &buffer_full_sem ); //v
}
}
void * consumer(void *param)
{
while (1) {
sem_wait( &buffer_full_sem ); //p
pthread_mutex_lock(&mutex);
msg_count -- ;
ConsumerProducts (buffer,sizeof(buffer));
printf("I am consumer msg_count = %d \n",msg_count);
usleep(100 *1000);
pthread_mutex_unlock(&mutex);
sem_post( &buffer_empty_sem ); //v
}
}
int main()
{
pthread_t tid_c;
pthread_t tid_p;
void * retv;
pthread_mutex_init(&mutex,NULL);
sem_init (&buffer_empty_sem, 0, 1); //unlock
sem_init (&buffer_full_sem, 0, 0); //lock
pthread_create(&tid_c , NULL , producer, NULL);
pthread_create(&tid_c , NULL , consumer, NULL);
pthread_join(tid_c,&retv);
pthread_join(tid_p,&retv);
while(1)
{
usleep(100 *1000);
}
return 0;
}
执行结果:
wythe@xxxx:~/linux-sys$ gcc pv.c -o pv -lpthread
pv.c: In function ‘producer’:
pv.c:47:4: warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]
usleep(100 *1000);
^
wythe@xxxx:~/linux-sys$ ./pv
I am producer msg_count = 1
consumer ......
I am consumer msg_count = 0
I am producer msg_count = 1
consumer ......
I am consumer msg_count = 0
I am producer msg_count = 1
consumer ......
I am consumer msg_count = 0
I am producer msg_count = 1
可以看到生产者与消费者有序执行生产与消费。