Travail de programmation du système d'exploitation Synchronisation 3 processus (mécanisme de sémaphore) (implémentation de pseudocode C ++)

Le titre

Il y a une assiette pour 5 fruits (pomme ou orange).
Chaque fois que le père met un fruit (pomme ou orange) dans l'assiette au hasard, le père met le fruit pas moins de 11 fois .
Le fils ne mange que des oranges et la fille ne mange que des pommes.

Veuillez programmer pour utiliser le mécanisme de sémaphore pour résoudre ce problème de synchronisation de processus.
Les informations imprimées comprennent l'état de la plaque, l'état de la planification et l'opération effectuée par le père, le fils ou la fille .

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

}

Résultat de l'opération

Plus de captures d'écran ici ...

Résultat de l'opération:

"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


Même série

2. Ordonnancement à 2 processus du travail de programmation du système d'exploitation (implémenté par C ++)
https://blog.csdn.net/qq_40939814/article/details/103548436

3. Synchronisation à 3 processus du travail de programmation du système d'exploitation (mécanisme de sémaphore) (implémentation du pseudocode C ++)
https://blog.csdn.net/qq_40939814/article/details/103548527

5. Opération de programmation du système d'exploitation Conversion à 5 adresses du système de pagination analogique (méthode de formule et méthode d'orthographe dure) (implémentation C ++)
https://blog.csdn.net/qq_40939814/article/details/103548645

Publié 9 articles originaux · Likes2 · Visites 559

Je suppose que tu aimes

Origine blog.csdn.net/qq_40939814/article/details/103548527
conseillé
Classement