Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55807
  • 博文数量: 12
  • 博客积分: 207
  • 博客等级: 入伍新兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-25 11:00
文章分类
文章存档

2013年(4)

2012年(8)

分类: LINUX

2012-10-31 18:43:42

 多线程哲学家进餐.rar  

//linux 下多线程哲学家进餐问题
/*运行过程:
root@bogon 未命名文件夹 3]# gcc pthread.c -lpthread
[root@bogon 未命名文件夹 3]# ./a.out
philosopher 0 start to eat, will cost 4 seconds!
philosopher 3 start to eat, will cost 8 seconds!
philosopher 5 start to eat, will cost 3 seconds!
..............................................
 
问题描述:有五位哲学家围绕着餐桌坐,每一位哲学家要么思考

要么等待,要么吃饭。为了吃饭,哲学家必须拿起两支筷子(分

别放于左右两端)不幸的是,筷子的数量和哲学家相等,所以每

只筷子必须由两位哲学家共享
基本思路:5个哲学家创建5个线程,但是只有五只筷子所以要有两位哲学家共享一只筷子,采用线程的同步问题解决方案设置信号量;
当没有筷子可用时就阻塞等待知道有相应信号量将其唤醒即有了可用筷子;*/



# include
# include
# include
# include

# define NUMBER 5

struct console {
    int chopstick[NUMBER];  // 筷子可用否状态数组 1表可用 0表不可用
    int eated[NUMBER];  // 哲学家吃好否状态数组 1表吃好 0表未吃
    pthread_mutex_t lock;  // 互斥锁
    pthread_cond_t philosopher[NUMBER];  // 哲学家可拿筷子信号
};

struct console buffer;

// 初始化
void init(struct console *buf)
{
    int i;
    for (i = 0; i < NUMBER; i++) {
        buf->chopstick[i] = 1;    //初始化
        buf->eated[i] = 0;
    }
    pthread_mutex_init(&buf->lock, NULL);    //互斥量初始化
    for (i = 0; i < NUMBER; i++)
        pthread_cond_init(&buf->philosopher[i], NULL);    //条件变量初始化
}

// 清理
void destroy(struct console *buf)
{
    int i;
    pthread_mutex_destroy(&buf->lock); //上锁;
    for (i = 0; i < NUMBER; i++)
        pthread_cond_destroy(&buf->philosopher[i]);//毁掉条件变量;
}

// 哲学家拿起筷子
void pick_chopstick(struct console *buf, int no)
{
    pthread_mutex_lock(&buf->lock); //上锁;
    while(1) {
        // 哲学家左右两边筷子可用时才拿起
        if (buf->chopstick[no] == 1 && buf->chopstick[(no+NUMBER-1)%NUMBER] == 1) {
            buf->chopstick[no] = 0; //用的时候将左边筷子状态置为0;
            buf->chopstick[(no+NUMBER-1)%NUMBER] = 0;//用的时候将右边筷子状态置为0;
            break;
        } else
            pthread_cond_wait(&buf->philosopher[no], &buf->lock);   //等待有筷子可以用;释放锁;
    }
    pthread_mutex_unlock(&buf->lock);   //释放互斥锁;
}

// 哲学家放下筷子
void drop_chopstick(struct console *buf, int no)
{
    pthread_mutex_lock(&buf->lock); //上锁;
    // 筷子设置成可用
    buf->chopstick[no] = 1;
    buf->chopstick[(no+NUMBER-1)%NUMBER] = 1;
    buf->eated[no] = 1; //设置吃好的信号;
    // 发送条件信号
    if (buf->eated[(no+1)%NUMBER] == 0) //如果左边筷子可用;
        pthread_cond_signal(&buf->philosopher[(no+1)%NUMBER]);//唤醒等待在buf->philosopher[(no+1)%NUMBER】条件变量上的拿筷子的信号;上锁;
    if (buf->eated[(no+NUMBER-1)%NUMBER] == 0) //如果右边筷子可用;
        pthread_cond_signal(&buf->philosopher[(no+NUMBER-1)%NUMBER]); //唤醒等待在buf->philosopher[(no+NUMBER-1)%NUMBER】条件变量上的拿筷子的信号;上锁;
    pthread_mutex_unlock(&buf->lock); //释放锁;
}

// 哲学家线程体
void *philosopher(void *arg)
{
    int no, stime;
    no = (int)arg;
    stime = rand()%8+2;  // 吃饭时间长度 2 - 9
    // 哲学家吃饭
    pick_chopstick(&buffer, no);
    printf("philosopher %d start to eat, will cost %d seconds!\n", no, stime);
    sleep(stime);
    printf("philosopher %d finish his eating!\n", no);
    drop_chopstick(&buffer, no);
    // 哲学家思考
    // ....
    return NULL;
}

int main()
{
    int i;
    time_t t;              //定义time_t类型的结构体变量所表示的时间不能晚于2038年1月18日19时14分07秒;
    pthread_t th[NUMBER];  //定义线程号;
    void *retval;          //定义返回值;
    srand((unsigned)time(&t));  // 生成随机数列
    init(&buffer);
    for (i = 0; i < NUMBER; i++)  // 生成哲学家线程
        pthread_create(&th[i], NULL, philosopher, (void *) i);
    for (i = 0; i < NUMBER; i++)  // 等待哲学家线程结束
        pthread_join(th[i], &retval);
    destroy(&buffer);   //distroy用于销毁线程组及其子组,但其中的所有线程都必须已经停止执行;
    return 0;
}



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