线程___同步

来源:互联网 发布:正大 数据恢复 编辑:程序博客网 时间:2024/06/14 08:11
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/ipc.h>#include <semaphore.h>#include <errno.h>#include <pthread.h>#define MYFIFO "/tmp/my_fifo"#define BUFFER_SIZE 3/*缓冲区的个数*/#define UNIT_SIZE 5/*每个缓冲区大小*/#define RUN_TIME 30/*线程运行时间*/#define DELAY_TIME_LEVELS 5.0int fd;time_t end_time;sem_t mutex,avail,full;const char *content = "hello";void *producer(void *arg){int len;int delay;while(time(NULL)<end_time){delay = (int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)/2.0)+1;sleep(delay);//sem_wait()和sem_trywait()都相当于P操作,二者的区别在于//sem_wait()会阻塞进程,而sem_trywait()会立即返回sem_wait(&avail); //空单元数sem_wait(&mutex);//互斥信号量,初始值为1printf("Producer: delay = %d\n",delay);if((len = write(fd,content,strlen(content)))==-1){if(errno = EAGAIN){printf("The FIFO has not been read yet!\n");}}else{printf("write %d to the FIFO\n",len);}//sem_post()相当于V操作,信号量加1,唤醒等待进程sem_post(&full);//非空单元数sem_post(&mutex);//互斥信号量}pthread_exit(0);}void *customer(void *arg){unsigned char buf[UNIT_SIZE];int len;int delay;while(time(NULL)<end_time){delay = (int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)/2.0)+1;sleep(delay);sem_wait(&full);//非空单元数sem_wait(&mutex);printf("\nCustomer: delay = %d\n",delay);memset(buf,0,UNIT_SIZE);if((len = read(fd,buf,UNIT_SIZE))==-1){if(errno==EAGAIN){printf("No data yet!\n");}}else{printf("Read %s from FIFO\n",buf);}sem_post(&avail);sem_post(&mutex);}pthread_exit(0);}int main(){pthread_t pro_id,cus_id;int ret;srand(time(NULL));end_time = time(NULL)+RUN_TIME;if(mkfifo(MYFIFO,O_CREAT|O_EXCL)<0 && (errno!=EEXIST)){printf("Cannot create FIFO\n");return errno;}fd = open(MYFIFO,O_RDWR);if(fd==-1){printf("Open fifo error!\n");return fd;}ret = sem_init(&mutex,0,1);ret += sem_init(&avail,0,BUFFER_SIZE);ret += sem_init(&full,0,0);if(ret!=0){printf("Any semaphore initialization failed\n");return ret;}pthread_create(&pro_id,NULL,producer,NULL);pthread_create(&cus_id,NULL,customer,NULL);pthread_join(pro_id,NULL);pthread_join(cus_id,NULL);close(fd);//unlink删除的是目录项,将文件链接计数减1,并没有真正的删除文件,可以//用来作为临时文件unlink(MYFIFO);}

0 0