Operating system programming job 3-process synchronization (semaphore mechanism) (C ++ pseudocode implementation)

topic

There is a plate for 5 fruits (apple or orange).
Every time the father puts a fruit (apple or orange) on the plate randomly, the father puts the fruit no less than 11 times .
The son only eats oranges, and the daughter only eats apples.

Please program to use the semaphore mechanism to solve this process synchronization problem.
The printed information includes the condition of the plate, the condition of scheduling, and the operation performed by the father, son, or daughter .

Code

//
// 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()));

}

operation result

No more screenshots here ...

operation result:

"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


Same series

2. Operating system programming job 2-process scheduling (implemented by C ++)
https://blog.csdn.net/qq_40939814/article/details/103548436

3. Operating system programming job 3-process synchronization (semaphore mechanism) (C ++ pseudocode implementation)
https://blog.csdn.net/qq_40939814/article/details/103548527

5. Operating system programming operation 5-address conversion of analog paging system (formula method and hard spelling method) (C ++ implementation)
https://blog.csdn.net/qq_40939814/article/details/103548645

Published 9 original articles · Likes2 · Visits 559

Guess you like

Origin blog.csdn.net/qq_40939814/article/details/103548527