计算机操作系统实验报告:

一.进程同步与互斥

1.实验名称:

进程同步与互斥

2.实验目的:

两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥。对CPU的速度和数目不做出任何的假设的前提下,并发进程互斥访问临界资源,是一个较好的解决方案。另外,还需要解决异步环境下的进程同步问题。所谓异步环境是指:相互合作的一组并发进程,其中每一个进程都以各自独立的、不可预知的速度向前推进;但它们又需要密切合作,以实现一个共同的任务,即彼此“知道”相互的存在和作用。
实验目的:分析进程争用资源的现象,学习解决进程同步与互斥的方法。
本实验属于设计型实验,实验者可根据自身情况选用合适的开发环境和程序架构。

3.实验原理:

信号量的PV操作与处理相关,P表示通过的意思,V表示释放的意思。所谓信号量,实际上就是用来控制进程状态的一个代表某一资源的存储单元。例如,P1和P2是分别将数据送入缓冲B和从缓冲B读出数据的两个进程,为了防止这两个进程并发时产生错误,狄克斯特拉设计了一种同步机制叫“PV操作”,P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P(S)时信号量S的值减1,若结果不为负则P(S)执行完毕,否则执行P操作的进程暂停以等待释放。执行V操作V(S)时,S的值加1,若结果不大于0则释放一个因执行P(S)而等待的进程。对P1和P2可定义两个信号量S1和S2,初值分别为1和0。进程P1在向缓冲B送入数据前执行P操作P(S1),在送入数据后执行V操作V(S2)。进程P2在从缓冲B读取数据前先执行P操作P(S2),在读出数据后执行V操作V(S1)。当P1往缓冲B送入一数据后信号量S1之值变为0,在该数据读出后S1之值才又变为1,因此在前一数未读出前后一数不会送入,从而保证了P1和P2之间的同步。
这一同步机制叫PV操作,这是狄克斯特拉用荷兰文定义的,因为在荷兰文中,通过叫passeren,释放叫vrijgeven,PV操作因此得名。这是在计算机术语中不是用英语表达的极少数的例子之一。

4.仪器与材料:

PC机,Devc++。

5.实验步骤(代码):

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>

const int SIZE_OF_BUFFER = 2;
int ProductID = 0;
int ConsumeID = 0;
int in = 0;
int out = 0;
int buffer[SIZE_OF_BUFFER];
bool p_ccontinue = true;
std::mutex mtx;
std::condition_variable full_cv;
std::condition_variable empty_cv;

void Produce() {
    std::cout << "Producing " << ++ProductID << "......succeed" << std::endl;
}

void Append() {
    std::cerr << "Appending a product ... ";
    buffer[in] = ProductID;
    in = (in + 1) % SIZE_OF_BUFFER;
    std::cerr << "Succeed" << std::endl;
    // 输出缓冲区当前状态
    for (int i = 0; i < SIZE_OF_BUFFER; i++) {
        std::cout << i << ":" << buffer[i];
        if (i == in) std::cout << "<----生产";
        if (i == out) std::cout << "<-----消费";
        std::cout << std::endl;
    }
}

void Take() {
    std::cerr << "Taking a product . . .";
    ConsumeID = buffer[out];
    buffer[out] = 0;
    out = (out + 1) % SIZE_OF_BUFFER;
    std::cerr << "Succeed" << std::endl;
    // 输出缓冲区当前状态
    for (int i = 0; i < SIZE_OF_BUFFER; i++) {
        std::cout << i << ":" << buffer[i];
        if (i == in) std::cout << "<----生产";
        if (i == out) std::cout << "<-----消费";
        std::cout << std::endl;
    }
}

void Consume() {
    std::cout << "Consuming " << ConsumeID << "...succeed" << std::endl;
}

void ProducerFunction() {
    while (p_ccontinue) {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        Produce();
        {
            std::unique_lock<std::mutex> lock(mtx);
            Append();
        }
        full_cv.notify_all();
    }
}

void ConsumerFunction() {
    while (p_ccontinue) {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        std::unique_lock<std::mutex> lock(mtx);
        full_cv.wait(lock, [] { return !p_ccontinue || buffer[out] != 0; });
        if (!p_ccontinue) return;
        Take();
        Consume();
        empty_cv.notify_all();
    }
}

int main() {
    std::vector<std::thread> producers;
    std::thread consumer(ConsumerFunction);

    for (int i = 0; i < 3; i++) {
        producers.emplace_back(ProducerFunction);
    }

    for (auto& producer : producers) {
        producer.join();
    }

    p_ccontinue = false;
    consumer.join();

    return 0;
}

6.问题即讨论

一个仓库可以存放K件物品。生产者每生产一件产品,将产品放入仓库,仓库满了就停止生产。消费者每次从仓库中去一件物品,然后进行消费,仓库空时就停止消费。

7.运行结果

**Producing 1…succeed
Appending a product …
Succeed
0:1<-----消费
1:0<----生产
Producing 2…succeed
Appending a product …
Succeed
0:1<----生产<-----消费
1:2
Taking a product . . .
Succeed
0:0<----生产
1:2<-----消费
Consuming 1…succeed
Taking a product . . .
Succeed
0:0<----生产<-----消费
1:0
Consuming 2…succeed
Producing 3…succeed
Appending a product …
Succeed
0:3<-----消费
1:0<----生产
Producing 4…succeed
Appending a product …
Succeed
0:3<----生产<-----消费
1:4
Taking a product . . .
Succeed
0:0<----生产
1:4<-----消费
Consuming 3…succeed
Taking a product . . .
Succeed
0:0<----生产<-----消费
1:0
Consuming 4…succeed
Producing 5…succeed
Appending a product …
Succeed
0:5<-----消费
1:0<----生产
Producing 6…succeed
Appending a product …
Succeed
0:5<----生产<-----消费
1:6
Taking a product . . .
Succeed
0:0<----生产
1:6<-----消费
Consuming 5…succeed
Producing 7…succeed
Appending a product …
Succeed
0:7
1:6<----生产<-----消费
在这里插入图片描述
**

Logo

鸿蒙生态一站式服务平台。

更多推荐