zoukankan      html  css  js  c++  java
  • 经典进程同步问题

    1、生产者-消费者问题

       问题描述是:有一群生产者进程在生产产品,此产品提供给消费者去消费。为使生产者和消费者进程能并发执行,在它们之间设置一个具有n个缓冲池,生产者进程可将它所生产的产品放入一个缓冲池中,消费者进程可从一个缓冲区取得一个产品消费。

       问题分析: 设两个同步信号量:一个说明空缓冲区的数目,用empty表示,初值为有界缓冲区的大小N,另一个说明已用缓冲区的数目,用full表示,初值为0。由于在执行生产活动和消费活动中要对有界缓冲区进行操作。有界缓冲区是一个临界资源,必须互斥使用,所以另外还需要设置一个互斥信号量mutex,其初值为1。

    semaphore mutex=1,empty=n,full=0;
    item buffer[n];   //缓冲区
    int in=out=0;   //输入、输出指针
    void producer()  

    {    

         while(1)

        {    

        …
         生产一个产品nextp;
        …
        wait(empty);  //等待空缓冲区的数目非0
        wait(mutex);  //等待无进程操作缓冲区    

        buffer[in]= nextp; //往Buffer [in]放产品
        in = (in+1) mod n;
        signal(mutex);  //允许其它进程操作缓冲区
        signal(full);   //增加已用缓冲区的数目
       }

    }

    void consumer()  

    {    

         while(1)

        {   ……

            wait(full); //等待已用缓冲区的数目非0
            wait(mutex); //等待无进程操作缓冲区
            nextc = buffer[out]; //从Buffer [out]取产品
            out = (out +1) mod n;
            signal(mutex); //允许其它进程操作缓冲区
            signal(empty); //增加空缓冲区的数目
                                       消费nextc产品;
         }

    }

    main()

    {

     cobegin{

       producer();

       consumer();

     }

    }

    }

    利用AND信号量解决生产者-消费者问题

    semaphore mutex=1,empty=n,full=0;
    item buffer[n];   //缓冲区
    int in=out=0;   //输入、输出指针
    void producer()  

    {    

         while(1)

        {    

        …
                         生产一个产品nextp;
        …
        swait(empty, mutex);
        buffer[in]= nextp; //往Buffer [in]放产品
        in = (in+1) mod n;
        ssignal(mutex, full);
         }

    }

    void consumer()  

    {    

         while(1)

        {        

            ……

            swait(full, mutex);
            nextc = buffer[out];  //从Buffer [out]取产品
            out = (out +1) mod n;
            signal(mutex, empty);
                消费nextc产品;
             }

    }

    2、读者-写者问题


    问题描述有两组并发进程: 读者(Reader)和写者(Writer),共享一组数据区或一个共享文件;                  要求:允许多个Reader同时执行读操作
          不允许Reader 、 Writer同时操作
          不允许多个Writer同时操作
    采用记录型信号量集解决读者-写者问题
    如果读者来:
    1)无读者、写者,新读者可以读
    2)有写者等待,但有其它读者正在读,则新读者也可以读
    3)有写者写,新读者等待

    如果写者来:
    1)无读者,新写者可以写
    2)有读者,新写者等待
    3)有其它写者,新写者等待


    设有两个信号量wmutex=1,rmutex=1
    另设一个全局变量readcount =0,表示正在读的读者数目
    wmutex用于读者和写者、写者和写者之间的互斥
    rmutex用于对readcount 这个临界资源的互斥访问
    Var rmutex,wmutext: semaphore :=1,1;
           Readcount: integer :=0;
           begin
           parbegin
           Reader:begin
                           repeat
                             wait(rmutex);  //等待无进程访问readcount
                             if (readcount=0) wait (wmutex); //等待无写者写
                             readcount := readcount+1;
                             signal(rmutex); //允许其它进程访问readcount
                             读
                             wait(rmutex); //等待无进程访问readcount
                             readcount := readcount-1;
                             if (readcount==0) signal(wmutex); //允许写者写
                             signal(rmutex); //允许其它进程访问readcount
                          until false
                          end
    Writer:begin
                           repeat
                             wait(wmutex); //等待无写者写,无读者读
                              写
                             signal(wmutex); //允许写者写,读者读
                           until false
                        end
        parend
        end
    增加一个限制条件:同时读的“读者”最多RN个

    mx表示“允许写”,初值是1
    L表示“允许读者数目”,初值为RN
    Var RN: integer;
           L, mx: semaphore :=RN,1;
    begin
           parbegin
           Reader:begin
                           repeat
                             Swait(L, 1, 1); //控制读者数目
                             Swait(mx, 1, 0);//无写者时(mx=1)读者
                                      可读; 有写者时(mx=0), 读者不可读
                             …
                             读
                             …
                             Ssignal(L, 1);
                          until false
                          end
    Writer:begin
                           repeat
                             Swait(mx,1,1;  L,RN,0); //在既无写者写(mx=1) 又无读者读(L=RN)时,新写者可写
                              写
                             Ssignal(mx,1); //允许其他读者、写者操作(mx=1)
                           until false
                        end
        parend
        end

  • 相关阅读:
    【Java】 Spring 框架初步学习总结(一)简单实现 IoC 和 AOP
    【Java】MyBatis框架初步学习总结
    CPLEX在Linux上的安装与配置
    CPLEX在IDEA上的配置
    WINDOWS系统下用BAT脚本运行JAR包
    启发式算法:遗传算法 (Genetic algorithm)
    Java基础知识:集合框架
    Java基础知识:Collection接口
    打印n位数的最大值
    我喜欢的博客
  • 原文地址:https://www.cnblogs.com/raymon/p/2547527.html
Copyright © 2011-2022 走看看