一、问题描述
有一个有限缓冲区和两个线程:生产者,消费者。他们分别往缓冲区写入产品和拿出产品。当缓冲区满时,生产者不能写必须等待;当缓冲区空时,消费者线程不能读,要等待。
二、实例
- /*product.c*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/ipc.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #include <pthread.h>
- #define FIFO "myfifo"
- #define N 5
- int lock_var;
- time_t end_time;
- char buf_r[100];
- sem_t mutex,full,avail;
- int fd;
- void productor(void *arg);
- void consumer(void *arg);
- int main(int argc,char *argv[])
- {
- pthread_t id1,id2;
- pthread_t mon_th_id;
- int ret;
- end_time = time(NULL)+30;
- /*create namepipe*/
- if((mkfifo(FIFO,O_CREAT|O_EXCL)<0) && (errno != EEXIST))
- printf("cannot create fifoserver\n");
- printf("preparing for reading bytes...");
- memset(buf_r,0,sizeof(buf_r));
- /*open pipe*/
- fd = open(FIFO,O_RDWR | O_NONBLOCK,0);
- if(fd == -1){
- perror("open");
- exit(1);
- }
- /*init sem valuable*/
- ret = sem_init(&mutex,0,1);
- ret = sem_init(&avail,0,N);
- ret = sem_init(&full,0,0);
- if(ret != 0){
- perror("sem_init");
- }
- /*create 2 pthread*/
- ret = pthread_create(&id1,NULL,(void *)productor,NULL);
- if(ret != 0)
- perror("pthread_cread1");
- ret = pthread_create(&id2,NULL,(void *)consumer,NULL);
- if(ret != 0)
- perror("pthread_cread2");
- pthread_join(id1,NULL);
- pthread_join(id2,NULL);
- exit(0);
- }
- /*product thread*/
- void productor(void *arg)
- {
- int i,nwrite;
- while(time(NULL) < end_time){
- /*p operate to the avail,mutex*/
- sem_wait(&avail);
- sem_wait(&mutex);
- /*productor write data to the pipe*/
- if((nwrite = write(fd,"hello",5)) == -1){
- if(errno == EAGAIN)
- printf("the FIFO has not been read yet,please try later\n");
- }
- else
- printf("write hello to the FIFO\n");
- /*v opertate to full,mutex*/
- sem_post(&full);
- sem_post(&mutex);
- sleep(1);
- }
- }
- /*consumer thread*/
- void consumer(void *arg)
- {
- int nolock = 0;
- int ret,nread;
- while(time(NULL) < end_time){
- sem_wait(&full);
- sem_wait(&mutex);
- memset(buf_r,0,sizeof(buf_r));
- if(nread = read(fd,buf_r,100) == -1){
- if(errno = EAGAIN)
- printf("no data yet\n");
- }
- printf("read %s from FIFO\n",buf_r);
- sem_post(&avail);
- sem_post(&mutex);
- sleep(1);
- }
- }
- [root@localhost net]# ./product
- preparing for reading bytes...write hello to the FIFO
- read hello from FIFO
- write hello to the FIFO
- read hello from FIFO
- write hello to the FIFO
- read hello from FIFO
- write hello to the FIFO
- read hello from FIFO
- write hello to the FIFO
- read hello from FIFO
- write hello to the FIFO
- read hello from FIFO