编写代码
本实验的代码中缓冲区拥有3个单元,每个单元为5个字节。为了尽量体现每个信号量的意义,在程序中生产过程和消费过程是随机(采取0~5s 的随机事件间隔)进行的,而且生产者的速度比消费者的速度平均快两倍左右。生产者一次生产一个单元的产品(放入hello字符串),消费者一次消费一个单元的产品。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MYFIFO "myfifo"
#define BUFFER_SIZE 3
#define UNIT_SIZE 5
#define RUN_TIME 30
#define DELAY_TIME_LEVELS 5
void *producer(void *arg);//生产者
void *customer(void *arg);//消费者
int fd;
time_t end_time;
sem_t mutex, full, avail;
int main(int argc, const char *argv[])
{
int ret;
pthread_t thrd_prd_id,thrd_cst_id;
srand(time(NULL));
end_time = time(NULL) + RUN_TIME;
//创建管道
if ((mkfifo(MYFIFO, 0644) < 0) && (errno != EEXIST)) {
perror("mkfifo error!");
exit(-1);
}
//打开管道
fd = open(MYFIFO, O_RDWR);
if (fd == -1) {
perror("open fifo error");
exit(-1);
}
//初始化信号量
ret = sem_init(&mutex, 0, 1);
ret += sem_init(&avail, 0, BUFFER_SIZE);
ret += sem_init(&full, 0, 0);
if (ret != 0) {
perror("sem_init error");
exit(-1);
}
//创建两个线程
ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);
if (ret != 0) {
perror("producer pthread_create error");
exit(-1);
}
ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);
if (ret != 0) {
perror("customer pthread_create error");
exit(-1);
}
pthread_join(thrd_prd_id, NULL);
pthread_join(thrd_cst_id, NULL);
sem_destroy(&mutex);
sem_destroy(&avail);
sem_destroy(&full);
close(fd);
unlink(MYFIFO);
return 0;
}
void *producer(void *arg)
{
int real_write;
int delay_time;
while (time(NULL) < end_time) {
delay_time = rand()%DELAY_TIME_LEVELS;
sleep(delay_time);
//p操作
sem_wait(&avail);
sem_wait(&mutex);
printf("\nproducer have delayed %d seconds\n", delay_time);
//生产者写入数据 执行的操作
if (-1 == (real_write = write(fd, "hello", UNIT_SIZE))) {
if (errno == EAGAIN) {
printf("The buffer is full, please wait for reading!\n");
}
} else {
printf("producer writes %d bytes to the FIFO\n", real_write);
printf("Now,the buffer left %d spaces!\n", avail);
}
//v操作
sem_post(&full);
sem_post(&mutex);
}
pthread_exit(NULL);
}
void *customer(void *arg)
{
unsigned char read_buffer[UNIT_SIZE];
int real_read;
int delay_time;
while (time(NULL) < end_time) {
delay_time = rand()%DELAY_TIME_LEVELS;
sleep(delay_time);
sem_wait(&full);
sem_wait(&mutex);
memset(read_buffer, 0, UNIT_SIZE);
printf("\nCustomer have delayed %d seconds\n", delay_time);
//消费 操作
if (-1 == (real_read = read(fd, read_buffer, UNIT_SIZE))) {
if (errno == EAGAIN) {
printf("The buffer is empty, please wait for writing!\n");
}
} else {
printf("customer reads %d bytes from the FIFO\n", real_read);
}
sem_post(&avail);
sem_post(&mutex);
}
pthread_exit(NULL);
}
执行结果如下:
root@jonathan-pc:~/test# gcc posixsem.c -lpthread -o posixsme
root@jonathan-pc:~/test# ./posixsme
producer have delayed 3 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 2 seconds
customer reads 5 bytes from the FIFO
producer have delayed 1 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 2 seconds
customer reads 5 bytes from the FIFO
producer have delayed 4 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
producer have delayed 0 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
producer have delayed 0 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 2 seconds
customer reads 5 bytes from the FIFO
Customer have delayed 0 seconds
customer reads 5 bytes from the FIFO
producer have delayed 0 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
producer have delayed 0 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 1 seconds
customer reads 5 bytes from the FIFO
Customer have delayed 1 seconds
customer reads 5 bytes from the FIFO
Customer have delayed 0 seconds
customer reads 5 bytes from the FIFO
producer have delayed 4 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 1 seconds
customer reads 5 bytes from the FIFO
producer have delayed 2 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 1 seconds
customer reads 5 bytes from the FIFO
producer have delayed 2 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
producer have delayed 1 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 4 seconds
customer reads 5 bytes from the FIFO
producer have delayed 1 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 1 seconds
customer reads 5 bytes from the FIFO
Customer have delayed 3 seconds
customer reads 5 bytes from the FIFO
producer have delayed 4 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 2 seconds
customer reads 5 bytes from the FIFO
producer have delayed 4 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
producer have delayed 0 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 0 seconds
customer reads 5 bytes from the FIFO
producer have delayed 3 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!
Customer have delayed 4 seconds
customer reads 5 bytes from the FIFO
producer have delayed 4 seconds
producer writes 5 bytes to the FIFO
Now,the buffer left 0 spaces!