操作系统经典问题

操作系统经典问题

1. 生产者消费者问题

分析:

针对单生产者单消费者模型解决的实际问题,创建两个线程,一个生产者,一个消费者,同时又empty 和 full 两个信号量,一个不允许在full 满时继续生产,一个不允许在empty为空时继续消耗,总共的缓冲池容量为10,经典大小,当每进入一个线程都会进行上锁操作,方式没有顺序执行,所有又有一个互斥信号量

代码:

/**
 * @file test.c++
 * @author Luke Tebo (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-03-22
 *
 * @copyright Copyright (c) 2022
 *
 * 使用c++11 解决生产者消费者问题
 */
#include <bits/stdc++.h>
#include <thread> //  thread
#include <future> // std::async std::future
#include <windows.h>
#include <mutex>  // std::mutex 加锁
#include <chrono> // std::chrono::seconds()
using namespace std;
const int N = 10;
int empty = N;
int full = 0;
int mutex = 1;
std::mutex mtx;
void Producer()
{
    while (1)
    {
        int num = 0;
        mtx.lock();
        if (full != N)
        {
            cout << "Producer : product " << ++num << endl;
            full++;
            empty--;
        }
        else
        {
            cout << "Producer : product stop!!!" << endl;
        }
        mtx.unlock();
        Sleep(100);
    }
}
void Consumer()
{

    while (1)
    {
        mtx.lock();
        int num = 0;
        if (empty != N)
        {
            cout << "Consumer : consume : " << ++num << endl;
            empty++;
            full--;

        }else{
            cout << "Consumer stop!! "<<endl;
        }
        mtx.unlock();
        Sleep(99);
    }
}
int main()
{

    thread thread1(Producer);
    thread thread2(Consumer);

    thread1.join();

    thread2.join();

    return 0;
}

结果:

1

2. 读者写者问题

分析:

创建了两个线程,一个使读者一个是写者,满足题目条件,当读者进行阅读的时候不允许写者进行写作,但允许多个读者只要创建多个读者线程即可,同时当有写者在进行写作的时候,不允许读者进行阅读,多有就有了wtx, rtx 两个参数,同时还有readcount 这个参数来记录读者线程,总共有几个需要上锁的过程,1. 当第一个读者开始阅读,他需要判断是否有写者,如果没有就对书上锁,2. 当最后一个读者结束阅读,他需要解开书的锁,让写者进入线程进行写作,3.当写者进行写作的时候不允许读者继续阅读

代码:

/**
 * @file test.c++
 * @author Luke Tebo (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-03-31
 *
 * @copyright Copyright (c) 2022
 *
 * 读者写者
 */
#include <iostream>
#include <future>
#include <mutex>
#include <chrono>
#include <windows.h>
using namespace std;
std::mutex wtx;    // 读写互斥锁
std::mutex rtx;    // 读读互斥锁
int readcount = 0; // 监控读者数量
void reader()
{
    while (true)
    {
        rtx.lock(); // 上锁
        if (readcount == 0)
        { // 如果是第一个读者,把书上锁
            wtx.lock();
        }
        readcount++;
        rtx.unlock();
        cout << "reader is reading " << endl;

        rtx.lock(); // 上锁
        readcount--;
        if (readcount == 0)
        { // 如果是最后一个读者
            wtx.unlock();
        }
        rtx.unlock();
        Sleep(100);
    }
}
void writer()
{
    while (true)
    {
        wtx.lock();
        cout << "the writer is writing " << endl;
        wtx.unlock();
        Sleep(100);
    }
}
int main()
{
    thread thread1(reader);
    thread thread2(writer);
    
    thread1.join();
    thread2.join();
    return 0;
}

结果:

1

3. 哲学家就餐问题

分析:

哲学家就餐问题,我的设计思路是,只有当这个哲学家两边的筷子都上锁成功,即两边的筷子都是可用的情况下那么这个哲学家就可以就餐,否则就继续思考,实现的方法也很简单,设计五个信号量,如果没有被使用就进行上锁,当这个哲学家两边的筷子都能够被正确上锁那么这个哲学家就可以停下思考进行就餐

代码:

/**
 * @file demo02.c++
 * @author Luke Tebo (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-03-31
 * 
 * @copyright Copyright (c) 2022
 * 
 * philosopher eating problem
 */
#include <iostream>
#include <future>
#include <mutex>
#include <chrono>
#include <thread>
using namespace std;
std::mutex chopstick[5];
void philosopher(int arg)
{
    int i = arg;
    int left, right;
    if( i == 4){
        left = i;
        right = 0;
    }else{
        left = i;
        right = i + 1;
    }
    while(1){

        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        chopstick[left].lock();
        cout<<"philosopher " << i << " fetches chopstick " << left << endl;

        // how to try lock?
        if(!chopstick[right].try_lock()){
            chopstick[left].unlock();
            continue;
        }

        cout<<"philosopher " << i << " fetches chopstick " << right << endl;
        cout<<"philosopher " << i << " is eating "<<endl;

        // sleep(2)
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        chopstick[right].unlock();
        cout<<"philosopher " << i <<" release chopstick " << right << endl;
        
        chopstick[left].unlock();
        cout<<"philosopher " << i <<" release chopstick " << left << endl;
        
    }

}
int main(){
    thread thread1(philosopher,1);
    thread thread2(philosopher,2);
    thread thread3(philosopher,3);
    thread thread4(philosopher,4);
    thread thread5(philosopher,5);

    thread1.join();
    thread2.join();
    thread3.join();
    thread4.join();
    thread5.join();
    return 0;
}

结果:

1

posted @   十月的十日  阅读(71)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩