Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279212
  • 博文数量: 109
  • 博客积分: 2116
  • 博客等级: 大尉
  • 技术积分: 1062
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-22 15:38
文章分类

全部博文(109)

文章存档

2013年(2)

2011年(16)

2010年(90)

2009年(1)

我的朋友

分类: 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为消费。

阅读(1286) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~