前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux】<信号量>解决<水果放取问题>【小拓展】——(设置整型turn,控制放的先后顺序)

【Linux】<信号量>解决<水果放取问题>【小拓展】——(设置整型turn,控制放的先后顺序)

作者头像
YY的秘密代码小屋
发布2024-11-03 08:04:53
640
发布2024-11-03 08:04:53
举报
文章被收录于专栏:C++系列

一.<信号量>相关实验回顾

1.回顾:使用<信号量>实现<线程互斥>——(解析:用信号量实现两个线程互斥输出1-10数字)

使用<信号量>实现<线程互斥>——(解析:用信号量实现两个线程互斥输出1-10数字)

2.回顾:巧妙运用< 信号量 >控制 <两个线程>之间<谁先执行>

巧妙运用< 信号量 >控制 <两个线程>之间<谁先执行>

3.回顾:巧妙运用<信号量>实现<控制n线程>之间<按什么顺序轮转>

巧妙运用<信号量>实现<控制n线程>之间<按什么顺序轮转>

二. 正文回顾:巧妙运用<信号量>解决<水果放取问题>(思维导图&代码演示&思路解析)

要求:

  • 一个盘子里只能放一个水果,爸爸往里面放苹果妈妈往里面放橘子,儿子专等吃橘子,女儿专等吃苹果;
  • 只要盘子空,爸爸或妈妈就可以往里面放水果;
  • 仅当盘子里有自己需要的水果时,儿子或女儿才可以取出吃;

解析:

  1. 设置三个信号量,plate=1,优先执行,面向父母端;两个信号量appleReady,orangeReady,分别设置成0,分别对应两个孩子
  2. 设置fruitOnPlate,fruitType,#define APPLE 1 #define ORANGE 2,表示父母端,放入苹果/橘子
  3. 如下面流程图一样设置 信号量等待(P操作),信号量唤醒(V操作)

流程图示意:

代码语言:javascript
复制
#include <stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  
#include <semaphore.h>  
#include <unistd.h>  

#define APPLE 1
#define ORANGE 2
//表示放入水果
int fruitOnPlate=0;
int fruitType=0;  

//设置信号量
sem_t plate, appleReady, orangeReady;  
  
void *father(void *arg) {  
    while (1) {  
        sem_wait(&plate);  
        
        fruitOnPlate = APPLE;  //放入苹果
        fruitType=APPLE;
         
        printf("Father put an apple.\n");  
        sem_post(&appleReady);  
        sleep(rand() % 10); //睡眠随机时间  
    }  
}  
  
void *mother(void *arg) {  
    while (1) {  
        sem_wait(&plate); 
        
        fruitOnPlate = ORANGE;       //放入橘子
        fruitType=ORANGE;
        
        printf("Mother put an orange.\n");  
        sem_post(&orangeReady); 
        sleep(rand() % 10); //睡眠随机时间   
    }  
}  
  
void *son(void *arg) {  
    while (1) {  
        sem_wait(&orangeReady); // 等待橘子
        if (fruitType == ORANGE) {  
            printf("Son ate an orange.\n");  
            sem_post(&plate);
        }  
    }  
}  
  
void *daugther(void *arg) {  
    while (1) {  
        sem_wait(&appleReady); // 等待苹果
        if (fruitType == APPLE) {  
            printf("Daugther ate an orange.\n");  
            sem_post(&plate);
        }  
    }  
}  
  
int main() {  
    pthread_t f_thread,m_thread,son_thread,dau_thread;
  
    sem_init(&plate, 0, 1);  
    sem_init(&appleReady, 0, 0);  
    sem_init(&orangeReady, 0, 0); 
  
    pthread_create(&f_thread, NULL, father, NULL);  
    pthread_create(&m_thread, NULL, mother, NULL);  
    pthread_create(&son_thread, NULL, son, NULL);  
    pthread_create(&dau_thread, NULL, daughter, NULL);  
  
    pthread_join(f_thread, NULL);  
    pthread_join(m_thread, NULL);  
    pthread_join(son_thread, NULL);  
    pthread_join(dau_thread, NULL);  
  
    sem_destroy(&plate);  
    sem_destroy(&appleReady);  
    sem_destroy(&orangeReady);  
  
    return 0;  
}

三.<信号量>解决<水果放取问题>【小拓展】——(设置整型turn,控制放的先后顺序)

要求:

  • 一个盘子里只能放一个水果,爸爸往里面放苹果妈妈往里面放橘子,儿子专等吃橘子,女儿专等吃苹果;
  • 只要盘子空,爸爸或妈妈就可以往里面放水果;
  • 仅当盘子里有自己需要的水果时,儿子或女儿才可以取出吃;

拓展要求:

  • 如何设计,使得必须父亲先放水果,以后父母交替放水果

解析:

  • 基本原理在上面【二. 正文回顾】中,这里侧重说明 【设置整型turn,控制放的先后顺序】
  1. 设置turn: 0表示父亲优先放,1表示母亲优先放
  2. 基于【二. 正文回顾】,只用考虑父母端与信号量plate的交互
  3. 父亲端操作,加入 if条件判断 :只有turn=0,才进入操作;母亲端同理

流程示意图:

代码语言:javascript
复制
#include <stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  
#include <semaphore.h>  
#include <unistd.h>  

#define APPLE 1
#define ORANGE 2
//表示放入水果
int fruitOnPlate=0;
int fruitType=0;  


//设置turn:0表示父亲优先放,1表示母亲优先放
turn=0;

//设置信号量
sem_t plate, appleReady, orangeReady;  
  
void *father(void *arg) {  
    while (1) {  
    if(turn ==0){
        sem_wait(&plate);  
        
        fruitOnPlate = APPLE;  //放入苹果
        fruitType=APPLE;
         
        printf("Father put an apple.\n");  
        sem_post(&appleReady);  
        sleep(rand() % 10); //睡眠随机时间
     }
     else{
        sleep(1);
        continue;
      }  
      turn=1;//切换到母亲
    }  
}  
  
void *mother(void *arg) {  
    while (1) {  
    if(turn ==0){
        sem_wait(&plate); 
        
        fruitOnPlate = ORANGE;       //放入橘子
        fruitType=ORANGE;
        
        printf("Mother put an orange.\n");  
        sem_post(&orangeReady); 
        sleep(rand() % 10); //睡眠随机时间   
      }
     else{
        sleep(1);
        continue;
      }  
      turn=0;//切换到父亲
    }  
}  
  
void *son(void *arg) {  
    while (1) {  
        sem_wait(&orangeReady); // 等待橘子
        if (fruitType == ORANGE) {  
            printf("Son ate an orange.\n");  
            sem_post(&plate);
        }  
    }  
}  
  
void *daugther(void *arg) {  
    while (1) {  
        sem_wait(&appleReady); // 等待苹果
        if (fruitType == APPLE) {  
            printf("Daugther ate an orange.\n");  
            sem_post(&plate);
        }  
    }  
}  
  
int main() {  
    pthread_t f_thread,m_thread,son_thread,dau_thread;
  
    sem_init(&plate, 0, 1);  
    sem_init(&appleReady, 0, 0);  
    sem_init(&orangeReady, 0, 0); 
  
    pthread_create(&f_thread, NULL, father, NULL);  
    pthread_create(&m_thread, NULL, mother, NULL);  
    pthread_create(&son_thread, NULL, son, NULL);  
    pthread_create(&dau_thread, NULL, daughter, NULL);  
  
    pthread_join(f_thread, NULL);  
    pthread_join(m_thread, NULL);  
    pthread_join(son_thread, NULL);  
    pthread_join(dau_thread, NULL);  
  
    sem_destroy(&plate);  
    sem_destroy(&appleReady);  
    sem_destroy(&orangeReady);  
  
    return 0;  
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.<信号量>相关实验回顾
    • 1.回顾:使用<信号量>实现<线程互斥>——(解析:用信号量实现两个线程互斥输出1-10数字)
      • 2.回顾:巧妙运用< 信号量 >控制 <两个线程>之间<谁先执行>
        • 3.回顾:巧妙运用<信号量>实现<控制n线程>之间<按什么顺序轮转>
        • 二. 正文回顾:巧妙运用<信号量>解决<水果放取问题>(思维导图&代码演示&思路解析)
        • 三.<信号量>解决<水果放取问题>【小拓展】——(设置整型turn,控制放的先后顺序)
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档