操作系统 程序设计作业3——进程同步(信号量机制) (C++伪代码实现)

题目

有一个盘子,可以放5个水果(苹果or桔子)。
父亲每次向盘子随机放入一个水果(苹果or桔子),父亲放入水果的次数不少于11次
儿子只吃桔子,女儿只吃苹果。

请编程使用信号量机制模拟解决此进程同步问题。
打印信息包括盘子的情况、调度的情况以及父亲、儿子或者女儿执行的操作

代码

//
// Created by Jintao on 2019/12/15.
//

// 题目:
// 有一个盘子,可以放5个水果(苹果or桔子)。
// 父亲每次向盘子随机放入一个水果(苹果or桔子),父亲放入水果的次数不少于11次。
// 儿子只吃桔子,女儿只吃苹果。
// 请编程使用信号量机制模拟解决此进程同步问题。
// 打印信息包括盘子的情况、调度的情况以及父亲、儿子或者女儿执行的操作。


#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<array>
#include<list>

/// 进程是哪一个
enum struct PType {
    father, son, dau
};

/// 水果类型枚举
enum struct Fruit {
    empty, orange, apple
};

/// 进程的数组, N代表数组容量大小, length代表进程个数(数组长度)
template<unsigned int N>
struct ProcArray {
    std::array<PType, N> names;

    ProcArray() {}

    /// 随机选取一个进程运行。其中 father被调度的概率是 son和dau的2倍
    PType randProc() {
        int choice = rand() % (N + 1) % N;
        return names[choice];
    }
};

/// 信号量
struct Semaphore {
    int value;
    std::list<PType> list;

    Semaphore() : value(0) {}

    Semaphore(int value) : value(value) {}


    /// 如果value>0 则运行,否则阻塞;value--;
    /// \return 阻塞: true, 不阻塞: false;
    bool P(PType pType);

    /// 如果value>=0 则运行,否则唤醒队列首;value--;
    void V();
};

/// 餐盘
template<unsigned int N>
struct Dish {
    std::list<Fruit> fruList;
    int emptyNum = N;

    /// 放水果  true: 成功; false: 失败
    void putFruit(Fruit fruit);

    /// 拿水果  true: 成功; false: 失败
    void removeFruit(Fruit fruit);

    void printDish();

};

void fatherRun();

void sonRun();

void dauRun();

void run(PType pType);

Semaphore empty(5), orange, apple;  // 3个信号量
Dish<5> dish;  // 容量为5的盘子
ProcArray<3> procArr;  // 3个进程
int runTime = 11;  // 运行11次  剩余运行次数


int main() {
    srand(time(nullptr));
    procArr.names = {PType::father, PType::son, PType::dau};
    while (runTime--) {
        run(procArr.randProc());
    }

    printf("\nSemaphore: \n");
    printf("empty: %d\n", empty.value);
    printf("orange: %d\n", orange.value);  // son
    printf("apple: %d\n", apple.value);  // dau
}

void run(PType pType) {
    printf("Before Running - ");
    dish.printDish();

    switch (pType) {
        case PType::father:
            printf("Running: Father\n");
            if (empty.P(PType::father)) {
                return;
            }
            fatherRun();
            break;
        case PType::son:
            printf("Running: Son\n");
            if (orange.P(PType::son)) {
                return;
            }
            sonRun();
            break;
        case PType::dau:
            printf("Running: Daughter\n");
            if (apple.P(PType::dau)) {
                return;
            }
            dauRun();
            break;
    }
    printf("After Running - ");
    dish.printDish();
    printf("\n");
}

void fatherRun() {


    switch (rand() % 2) {
        case 0:  // Fruit::orange
            // printInfo
            printf("Put a orange on dish\n");
            dish.putFruit(Fruit::orange);
            orange.V();
            break;

        case 1:  // Fruit::apple
            // printInfo
            printf("Put a apple on dish\n");
            dish.putFruit(Fruit::apple);
            apple.V();
            break;
    }
}


void sonRun() {

    // printInfo
    printf("Remove a orange from dish\n");
    dish.removeFruit(Fruit::orange);
    empty.V();
}

void dauRun() {

    // printInfo
    printf("Remove a apple from dish\n");
    dish.removeFruit(Fruit::apple);
    empty.V();
}


bool Semaphore::P(PType pType) {
    bool block = false;  // 阻塞
    value--;
    if (value < 0) {
        block = true;
        list.push_back(pType);
        printf("Block\n\n");

    }
    return block;
}

void Semaphore::V() {
    PType pType;
    value++;
    if (value <= 0) {
        printf("After Running - ");
        dish.printDish();
        pType = list.front();
        list.pop_front();
        switch (pType) {
            case PType::son:
                printf("\nAwake: Son\n");
                sonRun();
                break;
            case PType::dau:
                printf("\nAwake: Daughter\n");
                dauRun();
                break;
            default:
                break;
        }

    }

}


char *__fruitToStr(char *dest, Fruit fruit) {
    switch (fruit) {
        case Fruit::empty:
            strcpy(dest, "empty");
            break;
        case Fruit::orange:
            strcpy(dest, "orange");
            break;
        case Fruit::apple:
            strcpy(dest, "apple");
            break;
    }
    return dest;
}

template<unsigned int N>
void Dish<N>::putFruit(Fruit fruit) {
    if (!emptyNum)
        abort();
    else {
        fruList.push_back(fruit);
        emptyNum--;
        return;
    }
}

template<unsigned int N>
void Dish<N>::removeFruit(Fruit fruit) {
    for (auto it = fruList.begin(); it != fruList.end(); ++it) {
        if (*it == fruit) {
            fruList.erase(it);
            emptyNum++;
            return;
        }
    }
    abort();
}


template<unsigned int N>
void Dish<N>::printDish() {
    char fruitTemp[10];
    printf("Dish: ");
    if (emptyNum == N) {
        printf("none\n");
        return;
    }
    for (auto it = fruList.begin(); it != --fruList.end(); ++it) {
        printf("%s, ", __fruitToStr(fruitTemp, *it));
    }
    printf("%s\n", __fruitToStr(fruitTemp, fruList.back()));

}

运行结果

这里就不截图了…

运行结果:

"D:\programming\C C++\OSHomework\cmake-build-debug\homework.exe"
Before Running - Dish: none
Running: Son
Block

Before Running - Dish: none
Running: Daughter
Block

Before Running - Dish: none
Running: Daughter
Block

Before Running - Dish: none
Running: Daughter
Block

Before Running - Dish: none
Running: Father
Put a apple on dish
After Running - Dish: apple

Awake: Daughter
Remove a apple from dish
After Running - Dish: none

Before Running - Dish: none
Running: Father
Put a apple on dish
After Running - Dish: apple

Awake: Daughter
Remove a apple from dish
After Running - Dish: none

Before Running - Dish: none
Running: Father
Put a orange on dish
After Running - Dish: orange

Awake: Son
Remove a orange from dish
After Running - Dish: none

Before Running - Dish: none
Running: Daughter
Block

Before Running - Dish: none
Running: Father
Put a orange on dish
After Running - Dish: orange

Before Running - Dish: orange
Running: Father
Put a orange on dish
After Running - Dish: orange, orange

Before Running - Dish: orange, orange
Running: Father
Put a orange on dish
After Running - Dish: orange, orange, orange


Semaphore:
empty: 2
orange: 3
apple: -2

进程已结束,退出代码 0


同系列

2、操作系统 程序设计作业2——进程调度 (C++实现)
https://blog.csdn.net/qq_40939814/article/details/103548436

3、操作系统 程序设计作业3——进程同步(信号量机制) (C++伪代码实现)
https://blog.csdn.net/qq_40939814/article/details/103548527

5、操作系统 程序设计作业5——模拟分页系统的地址变换(公式法和硬拼法) (C++实现)
https://blog.csdn.net/qq_40939814/article/details/103548645

发布了9 篇原创文章 · 获赞 2 · 访问量 559

猜你喜欢

转载自blog.csdn.net/qq_40939814/article/details/103548527