美文网首页想法
操作系统课程设计(实验三 信号量解决消费者生产者问题)

操作系统课程设计(实验三 信号量解决消费者生产者问题)

作者: 林木木_f297 | 来源:发表于2019-10-26 09:59 被阅读0次
    开搞!

    实验题目

    实验三 使用信号量解决生产者/消费者同步问题(lab3)
    实验目的:
    使用操作系统信号量机制,编写程序解决生产者/消费者同步问题。
    实验内容:
    1.理解Nachos的信号量是如何实现的;
    2.生产者/消费者问题是如何用信号量实现的;
    3.在Nachos中是如何创建并发线程的;
    4.在Nachos下是如何测试和debug的.
    实验环境:
    虚拟机下Ubuntu Linux 16.04 LTS系统,nachos-3.4内核管理模块和MIPSCPU软件模拟模块,代码在lab3文件夹下面实现。

    直接开搞!!!

    刚开始我们打开lab3,无脑make一波


    可怕的事儿还是发生啦.png

    !
    这一下就十分令人蒙b
    打开了老师给的指导教程。
    !!!
    原来这个实验是一个半成品!
    我们需要自己完善。
    目前已完善的有:

    main.cc
    ring.cc
    ring.h

    剩下的prodcons就需要我们自己去努力了
    那么我们就开始读文件了:先从ring开始

    读文件

    ring

    class slot {
        public:
        slot(int id, int number);
        slot() { thread_id = 0; value = 0;};
        
        int thread_id;
        int value;
        };
    
    
    class Ring {
      public:
        Ring(int sz);    // Constructor:  initialize variables, allocate space.
        ~Ring();         // Destructor:   deallocate space allocated above.
    
        
        void Put(slot *message); // Put a message the next empty slot.
        
        void Get(slot *message); // Get a message from the next  full slot.
                                                
        int Full();       // Returns non-0 if the ring is full, 0 otherwise.
        int Empty();      // Returns non-0 if the ring is empty, 0 otherwise.
        
      private:
        int size;         // The size of the ring buffer.
        int in, out;      // Index of 
        slot *buffer;       // A pointer to an array for the ring buffer.
    };
    

    可以看到,这里定义了两个类,一个是slot,一个是ring。
    通过分析代码,我们得到以下结论:

    Ring是一个环形缓冲类,给消费者和生产者使用
    slot是被放置在ring当中的一个包装了线程的东西,存着id和value这两个信息。

    main

    感觉和上一个实验的main差别不大,没什么可分析的

    prodcons

    这个就是我们的重头戏了,经过阅读,发现有三个部分需要我们填充
    -生产者
    -消费者
    -信号量
    这三个的基础方法都在ring中有定义,我们只需要捏起来就可以了


    image.png

    还要注意到上面的一个变量声明,这里给我们提供了信号量的定义、申请和释放的方法。也就是说,锁是在这里定义的。
    那么我们就发现,我们不知道semaphore是什么东西,发现他的代码在thread里面存在,那么就去看一下它的代码。


    如图所示
    发现这个就是我们的信号量嘛,有PV操作,可以实现锁。

    开始写代码

    生产者


    需要增加代码来补充message携带的信息;

    message->thread_id = which;
        message->value = num;
    

    增加向Ring中放消息前的信号量操作代码;

    // Put the code for synchronization before  ring->Put(message) here.
          // ...
        nempty->P();
        mutex->P();
          ring->Put(message);
    

    增加向Ring 中放消息后的信号量操作代码。

          // Put the code for synchronization after  ring->Put(message) here.
          // ...
        mutex->V();
        nfull->V();
    

    消费者


    需要增加从Ring中读消息前的信号量操作代码;

    // Put the code for synchronization before ring->Get(message) here.
          // ...
          nfull->P();
          mutex->P();
          ring->Get(message);
    

    从Ring 中读消息后的信号量操作代码

          mutex->V();
          nempty->V();
    

    信号量

    需要增加构造所有信号量代码;

        mutex = new Semaphore("mutttt",1);
        nfull = new Semaphore("nfull",0);
        nempty = new Semaphore("empty",BUFF_SIZE);
    

    增加构造缓冲池的代码;

     ring = new Ring(BUFF_SIZE);
    

    创建生产者线程的代码;

    producers[i] = new Thread(prod_names[i]);
          producers[i]->Fork(Producer,i);
    

    创建消费者线程的代码

    consumers[i] = new Thread(cons_names[i]);
          consumers[i] -> Fork(Consumer,i);
    

    写完了这些部分,再次make一波

    报错!!!

    问题出在哪里呢?


    报错

    发现是因为缺少了creat、write、exit和一些拼写错误
    拼写错误修改中。。。
    对于那几个函数缺失的问题,上网搜集资料
    发现下面这个解决方案可以:
    导入头文件

    #include <unistd.h> //库中包含write方法
    #include <fcntl.h> //库中包含creat方法
    

    再把ring.cc中的exit方法剪切到ring.h中
    保存,跑!
    make成功
    ./nachos试一下


    成功

    欣慰
    打开源目录,发现多了两个文件,里面就是存着我们生产者、消费者的相关信息。


    0
    1
    发现生产者生产的居然全部都被消费者1抢走了
    然后根据指导书上,添加一下随机数种子
    添加随机数种子的方法在指导书里前面一个地方写了,是这样的
    -rs seed-number 
    

    于是我们试验一下


    命令 0
    1

    果然变了,那么实验就到此为止写完了。

    相关文章

      网友评论

        本文标题:操作系统课程设计(实验三 信号量解决消费者生产者问题)

        本文链接:https://www.haomeiwen.com/subject/plbevctx.html