分类: LINUX
2010-07-09 14:47:40
今天的实验主要练习用信号量处理线程间的同步互斥问题。采用的还是经典的“生产者消费者”模型。缓冲区是临界资源用FIFO来模拟。
线程的同步机制主要有互斥锁和信号量两种,前者适用于一种可用资源的情况,后者适用于多种可用资源的情况。
本实验设置了3个信号量。两个解决同步,一个解决互斥。
源代码来自华清远见:
#include
#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.0
int fd;
time_t end_time;
sem_t mutex, full, avail;
void *producer(void *arg)
{
int real_write;
int delay_time = 0;
while(time(NULL) < end_time)
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) / 2.0) + 1;
sleep(delay_time);
sem_wait(&avail);//P
sem_wait(&mutex);//P
printf("\nproducer: delay = %d\n", delay_time);
if((real_write = write(fd, "hello", UNIT_SIZE)) == -1)//生产
{
if(errno == EAGAIN)
{
printf("the FIFO has not been read yet,please try later.\n");
}
}
else
{
printf("write %d to the FIFO\n", real_write);
}
sem_post(&full);//V
sem_post(&mutex);//V
}
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 = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
sem_wait(&full);//P
sem_wait(&mutex);//P
memset(read_buffer, 0, UNIT_SIZE);//清空缓冲
printf("\ncustomer: delay = %d\n", delay_time);
if((real_read = read(fd, read_buffer, UNIT_SIZE)) == -1)//消费
{
if(errno == EAGAIN)
{
printf("no data yet\n");
}
}
printf("read %s from FIFO\n", read_buffer);
sem_post(&avail);//V
sem_post(&mutex);//V
}
pthread_exit(NULL);
}
int main()
{
pthread_t thrd_prd_id, thrd_cst_id;
//pthread_t mon_th_id;
int ret;
srand(time(NULL));
end_time = time(NULL) + RUN_TIME;
if((mkfifo(MYFIFO, O_CREAT|O_EXCL) < 0) && (errno != EEXIST))//创建管道
{
printf("cannot creat fifo\n");
return errno;
}
fd = open(MYFIFO, O_RDWR);//打开管道
if(fd == -1)
{
printf("open fifo errno\n");
return fd;
}
ret = sem_init(&mutex, 0, 1);//初始化信号量mutex
ret += sem_init(&full, 0 , 0);//full
ret += sem_init(&avail, 0, BUFFER_SIZE);//avail
if(ret != 0)
{
printf("Any semaphore initialization failed\n");
return ret;
}
ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);//创建生产者线程
if(ret != 0)
{
printf("Creat producer thread errno.\n");
return ret;
}
ret = pthread_create(&thrd_prd_id, NULL, customer, NULL);//创建消费者线程
if(ret != 0)
{
printf("Creat customer thread errno.\n");
return ret;
}
pthread_join(thrd_prd_id, NULL);
pthread_join(thrd_cst_id, NULL);
close(fd);//关闭管道
unlink(MYFIFO);
return 0;
}
编译运行,结果如下:
Write为生产,read为消费。