精华内容
下载资源
问答
  • 操作系统经典同步问题
    千次阅读
    2019-05-28 18:26:02

    操作系统经典进程同步问题之生产者-消费者问题

    • 先通俗的理解一下什么是同步:进程同步其实好比就是一件事情必须先做什么再做什么,否则不能继续下去,就比如有3个进程A,B,CA是输出进程,B是处理进程,C是输出进程,假如A进程没有输入数据,那么B进程就无法进行处理,只有A输出了,B才能继续,这就是进程同步

    一、生产者-消费者问题

    1.问题描述:生产者-消费者模型描述的是有一群生产者进程在生产产品,并将这些产品提供给消费者进程并发进行,具备并发程序的典型特征。PCM为使生产者进程和消费者进程并发进行,在它们之间设置一个具有多个缓冲区的缓冲池生产者进程可以将其所生产的产品放入一个缓冲区中,消费者进程可以从一个缓冲区中取得产品去消费。尽管所有的生产者进程和消费者进程都是以异步方式运行的,但他们之间必须保持同步,既不允许消费者进程从空的缓冲区中拿产品,也不允许生产者进程向满缓冲区中放产品。

    2.问题分析:我们可以利用一个数组来表示上述的具有n各缓冲单元的缓冲区。用输入指针in作写指针,每当生产者进程生产并投放一个产品时,in加1;同理,out指针作为读指针,每当消费者拿走一个产品时out便加1。由于缓冲区是循环队列,则加1写成,in=(in+1)mod n,out同理。当(in+1)mod n=out时,缓冲区满,当in=out时,缓冲区为空。此外还引入了count,当生产者生产并放入时加1,消费者拿走时则减1.

    3.程序描述
    共享变量

    	int n, buffer[n];
    	int in, out;    //in,out[0,n-1]
    	int count;     //count[0,n]
    
    

    伪代码:

    void producer() {
    		producer an item in nextp;
    		while (count == n) {
    			buffer[in] = nextp;
    			in = (in + 1)mod n;
    			count++;
    		}
    		
    void consumer() {
    			while (count==0) {
    				nextc = buffer[out];
    				out = (out + 1)mod n;
    				count--;
    				consumer the item in nextc;
    			}
    
    
    

    利用记录型信号量解决

    	int mutex = 0, empty = n, full = 0;
    	int buffer[n];
    	int in = 0, out = 0;
    	void producer() {
    		producer an item, nextp;//nextp为生产的产品
    		wait(empty);
    		wait(mutex);
    		buffer[in] = nextp;
    		in = (in + 1)mod n;
    		signal(mutex);
    		signal(full);
    	}
    	void consumer() {
    		wait(full);
    		wait(mutex);
    		nextc = buffer[out];
    		out = (out + 1)mod n;
    		signal(mutex);
    		signal(empty);
    		consumer nextc;
    	}
    
    

    记录型信号量中wait(),和signal()操作如下:

    	void wait(s) {  //s为信号量
    		s--;
    		if (s < 0) {
    			block(s,L)//阻塞
    		}
    	}
     
    	void signal(s) {
    		s++;
    		if (s <=0) {
    			wakeup(s, L);//唤醒
    		}
    
    

    每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对出现,注意wait(empty)在生产者进程中,每个程序中多个wait操作不可颠倒,否则容易发生死锁的现象。

    更多相关内容
  • 试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。 提示:设置一个信号量表示可否向盘中放水果,一个信号量表示可否取桔子,一个信号量表示可否取苹果。 实验目的: 深入掌握进程、线程同步机制——信号量机制...

    题目

    桌上有一空盘,最多允许存放一只水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。
    试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。

    提示:设置一个信号量表示可否向盘中放水果,一个信号量表示可否取桔子,一个信号量表示可否取苹果。

    实验目的:

    深入掌握进程、线程同步机制——信号量机制的原理与应用;
    掌握Windows编程中信号量机制的使用方法;
    掌握Windows下线程的控制方法;
    可进行简单的信号量应用编程。

    解题思路

    下面展示一些 内联代码片

    从这个题意可以得出,这个实验一共有3个进程,
    分别是父亲,儿子,女儿。
    且要设置3个信号量,
    S:表示是否可以向盘子防水果  初值为1 表示盘子为空
    S0:表示盘子中放的是桔子 初值为0  表示盘子内不是桔子
    S1:表示盘子中放的是苹果 初值为0 表示盘子内不是苹果
    
    // 进行P,V操作(P,V操作为原子操作不可被打断)
    //父亲
    father()
    { while(1){
      P(S);//申请盘子的使用权
      将水果放入盘中
      if(是桔子){
      V(S0);//释放是桔子的信号量,S0+1)
      }
      else{
      V(S1);//释放是苹果的信号量,S1+1)
      }
    }
    }
    
    //儿子
    son() 
    {while(1){
      p(S0);//等待盘子中是桔子的信号
      取桔子;
      V(S);释放盘子的使用权
      吃桔子;
    }
    }
    
    //女儿
    daughter() 
    {while(1){
      p(S1);//等待盘子中是苹果的信号
      取苹果;
      V(S);释放盘子的使用权
      吃苹果;
    }
    }
    

    源码实现

    #include <windows.h>
    #include <iostream>
    #include<stdio.h>
    
    bool g_continue = true; //控制程序结束
    HANDLE g_hS; //当盘子为空时的线程 
    HANDLE g_hS0; //当盘子中放的是桔子线程 
    HANDLE g_hS1; //当盘子中放的是苹果线程 
    DWORD WINAPI father(LPVOID); //定义父亲线程
    DWORD WINAPI son(LPVOID); //定义儿子线程
    DWORD WINAPI daughter(LPVOID);//定义女儿线程
    int main()  
    {  
     //创建各个互斥与资源信号量  
     g_hS = CreateSemaphore(NULL,1,1,NULL);  //盘子中是否有水果 
     g_hS0 = CreateSemaphore(NULL,0,1,NULL);  //盘子中的水果为桔子 
     g_hS1 = CreateSemaphore(NULL,0,1,NULL);  //盘子中的水果为苹果 
    
    //其中第2和3个参数为信号量的初始值和最大值
    
     const unsigned short father_COUNT = 0; //声明父亲
     const unsigned short son_COUNT = 0; //声明儿子
     const unsigned short daughter_COUNT = 0;//声明女儿
     
     //总的线程数 
     const unsigned short THREADS_COUNT = father_COUNT+son_COUNT+daughter_COUNT ;  
     HANDLE hThreads[THREADS_COUNT]; //各线程的handle  
     DWORD fatherID[father_COUNT]; //父亲线程的标识符
     DWORD sonID[son_COUNT]; //儿子线程的标识符  
     DWORD daughterID[daughter_COUNT]; //女儿线程的标识符
     
    //创建父亲进程
    
     hThreads[0]=CreateThread(NULL,0,father,NULL,0,&fatherID[0]);  
      if (hThreads[0]==NULL) return -1;  
     
    //创建儿子进程
      
     hThreads[1]=CreateThread(NULL,0,son,NULL,0,&sonID[0]);  
      if (hThreads[1]==NULL) return -1;  
     
    //创建女儿进程
     
     hThreads[2]=CreateThread(NULL,0,daughter,NULL,0,&daughterID[0]);  
      if (hThreads[2]==NULL) return -1;  
    
    
     while(g_continue){  
      if(getchar()){ //按回车后终止程序运行  
    	  g_continue = false;  
      }  
     }  
    
     return 0;  
    }  
    //父亲放水果的操作,输出  
    
    void eat()  
    {  
     std::cerr << "儿子吃桔子" << std::endl;  
    }  
    
     
    void eat1()  
    {  
     std::cerr << "女儿吃苹果" << std::endl;  
    }  
    
    //父亲进程  
    DWORD WINAPI father(LPVOID lpPara)  
    {  
     while(g_continue){  
      WaitForSingleObject(g_hS,INFINITE);   
      
      int juzhi=rand()%2; //设置了一个随机数,来模拟父亲放的是什么水果 
      Sleep(1500);//方便观察实验结果
      if(juzhi==1){
      	  printf("父亲放入了一个桔子\n");
      	  Sleep(1000);
          ReleaseSemaphore(g_hS0,1,NULL); 
      }
      else{
      	printf("父亲放入了一个苹果\n"); 
      	Sleep(1000);
    	   ReleaseSemaphore(g_hS1,1,NULL); 
     }
     }  
     return 0;  
    }  
    
    //儿子进程 
    DWORD WINAPI son(LPVOID lpPara)  
    {  
     while(g_continue){  
      WaitForSingleObject(g_hS0,INFINITE); 
       eat(); 
       Sleep(1500); 
      ReleaseSemaphore(g_hS,1,NULL);   
     }  
     return 0;  
    }    
    
    //女儿进程 
    DWORD WINAPI daughter(LPVOID lpPara)  
    {  
     while(g_continue){  
      WaitForSingleObject(g_hS1,INFINITE);    
      eat1(); 
      Sleep(1500); 
      ReleaseSemaphore(g_hS,1,NULL); 
     }  
     return 0;  
    }    
    
    
    实验结果

    在这里插入图片描述
    Thanks

    展开全文
  • 生产者和消费者问题是计算机同步互斥的经典问题,其意思就是生产者把生产出来的产品放在仓库里,消费者把产品从仓库里取出来。仓库属于临界区,生产者和消费者一次只能一个进入临界区中。两个进程之间就有一个同步...

    一、生产者消费者问题

    生产者和消费者问题是计算机同步互斥的经典问题,其意思就是生产者把生产出来的产品放在仓库里,消费者把产品从仓库里取出来。仓库属于临界区,生产者和消费者一次只能一个进入临界区中。两个进程之间就有一个同步互斥问题,下面我将对该问题进行详细介绍。

    二、思路分析

    对于一个仓库,仓库的容量是有限的,对应的临界资源是有限的,假设仓库的容量是n。当仓库装满了,就不能允许生产者进行访问,如果仓库满了,生产者再把产品放进仓库就会导致仓库爆仓。与此同时,当库存为零时也不能允许消费者进入,这个不符合逻辑。基于这种思路,我们设置三个信号量empty、full和一个互斥锁。

    三、代码实现

    semaphore mutex=1;
    semaphore empty=n;
    semaphore full=0;
    //生产者
    producer(){
    	while(1){
    		//生产者生产产品
    		P(empty);//判断仓库是否为空
    		P(mutex);//判断是否可以进入临界区
    		//放产品
    		V(full);//仓库里有多少产品
    		V(mutex);//释放互斥锁
    	}
    }
    
    //消费者
    consumer(){
    	while(1){
    		P(full);//判断仓库是否有产品
    		P(mutex);//判断是否可以进入临界区
    		//放消费产品
    		V(empty);//仓库里增加一个空位
    		V(mutex);//释放互斥锁
    	}
    }
    
    展开全文
  • 在进程同步中,经典同步问题有:生产者-消费者问题、读者-写者问题、哲学家进餐问题。 一、生产者与消费者问题问题描述:使用一个缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品;只有缓冲区不为...

     

    在进程同步中,经典的同步问题有:生产者-消费者问题、读者-写者问题、哲学家进餐问题。

    一、生产者与消费者问题:

    问题描述:使用一个缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品;只有缓冲区不为空,消费者才可以拿走物品。

    1、使用信号量实现生产者-消费者问题:

    down : 如果信号量大于 0 ,执行 -1 操作;如果信号量等于 0,进程睡眠,等待信号量大于 0;

    up :对信号量执行 +1 操作,唤醒睡眠的进程让其完成 down 操作。

    因为缓冲区属于临界资源,因此需要使用一个互斥量 mutex 来控制对缓冲区的互斥访问。

    为了同步生产者和消费者的行为,需要记录缓冲区中物品的数量。数量可以使用信号量来进行统计,这里需要使用两个信号量:empty 记录空缓冲区的数量,full 记录满缓冲区的数量。其中,empty 信号量是在生产者进程中使用,当 empty 不为 0 时,生产者才可以放入物品;full 信号量是在消费者进程中使用,当 full 信号量不为 0 时,消费者才可以取走物品。

    注意,不能先对缓冲区进行加锁,再测试信号量。也就是说,不能先执行 down(mutex) 再执行 down(empty)。如果这么做了,那么可能会出现这种情况:生产者对缓冲区加锁后,执行 down(empty) 操作,发现 empty = 0,此时生产者睡眠。消费者不能进入临界区,因为生产者对缓冲区加锁了,消费者就无法执行 up(empty) 操作,empty 永远都为 0,导致生产者永远等待下,不会释放锁,消费者因此也会永远等待下去。

    #define N 100
    typedef int semaphore;
    semaphore mutex = 1;
    semaphore empty = N;
    semaphore full = 0;
    
    void producer() {
        while(TRUE) {
            int item = produce_item();
            down(&empty);
            down(&mutex);
            insert_item(item);
            up(&mutex);
            up(&full);
        }
    }
    
    void consumer() {
        while(TRUE) {
            down(&full);
            down(&mutex);
            int item = remove_item();
            consume_item(item);
            up(&mutex);
            up(&empty);
        }
    }

    2、使用管程实现生产者-消费者问题:

     // 管程
     monitor ProducerConsumer
        condition full, empty;
        integer count := 0;
        condition c;

        procedure insert(item: integer);
        begin
            if count = N then wait(full);
            insert_item(item);
            count := count + 1;
            if count = 1 then signal(empty);
        end;

        function remove: integer;
        begin
            if count = 0 then wait(empty);
            remove = remove_item;
            count := count - 1;
            if count = N -1 then signal(full);
        end;
    end monitor;

    // 生产者客户端
    procedure producer
    begin
        while true do
        begin
            item = produce_item;
            ProducerConsumer.insert(item);
        end
    end;

    // 消费者客户端
    procedure consumer
    begin
        while true do
        begin
            item = ProducerConsumer.remove;
            consume_item(item);
        end
    end;

     

    二、读者-写者问题:

    允许多个进程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。

    一个整型变量 count 记录在对数据进行读操作的进程数量,一个互斥量 count_mutex 用于对 count 加锁,一个互斥量 data_mutex 用于对读写的数据加锁。

    typedef int semaphore;
    semaphore count_mutex = 1;
    semaphore data_mutex = 1;
    int count = 0;
    
    void reader() {
        while(TRUE) {
            down(&count_mutex);
            count++;
            if(count == 1) down(&data_mutex); // 第一个读者需要对数据进行加锁,防止写进程访问
            up(&count_mutex);
            read();
            down(&count_mutex);
            count--;
            if(count == 0) up(&data_mutex);
            up(&count_mutex);
        }
    }
    
    void writer() {
        while(TRUE) {
            down(&data_mutex);
            write();
            up(&data_mutex);
        }
    }

     

    三、哲学家进餐问题:

    五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭以及思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。

    下面是一种错误的解法,考虑到如果所有哲学家同时拿起左手边的筷子,那么就无法拿起右手边的筷子,造成死锁。

    #define N 5
    
    void philosopher(int i) {
        while(TRUE) {
            think();
            take(i);       // 拿起左边的筷子
            take((i+1)%N); // 拿起右边的筷子
            eat();
            put(i);
            put((i+1)%N);
        }
    }

    为了防止死锁的发生,可以设置两个条件:

    • 必须同时拿起左右两根筷子;
    • 只有在两个邻居都没有进餐的情况下才允许进餐。
    #define N 5
    #define LEFT (i + N - 1) % N // 左邻居
    #define RIGHT (i + 1) % N    // 右邻居
    #define THINKING 0
    #define HUNGRY   1
    #define EATING   2
    typedef int semaphore;
    int state[N];                // 跟踪每个哲学家的状态
    semaphore mutex = 1;         // 临界区的互斥
    semaphore s[N];              // 每个哲学家一个信号量
    
    void philosopher(int i) {
        while(TRUE) {
            think();
            take_two(i);
            eat();
            put_two(i);
        }
    }
    
    void take_two(int i) {
        down(&mutex);
        state[i] = HUNGRY;
        test(i);
        up(&mutex);
        down(&s[i]);
    }
    
    void put_two(i) {
        down(&mutex);
        state[i] = THINKING;
        test(LEFT);
        test(RIGHT);
        up(&mutex);
    }
    
    void test(i) {         // 尝试拿起两把筷子
        if(state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] !=EATING) {
            state[i] = EATING;
            up(&s[i]);
        }
    }

     

     

    文章转自:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F.md#%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8

    展开全文
  • 操作系统同步互斥问题

    千次阅读 2018-09-29 16:38:08
    操作系统同步互斥问题 一些经典的例子就不列举了,接下来讲一些在学习操作系统课程的过程中所遇到的几个进程同步的题目。 1.取放水果问题 用基本记录型信号量解决如下同步关系:一空盘放一水果,父放梨,母放橘,儿...
  • 操作系统经典进程同步问题

    万次阅读 多人点赞 2017-12-02 15:20:55
    这里介绍三中进程同步问题:  1.生产者-消费者问题  2.读者-写者问题  3.哲学家进餐问题 一、生产者-消费者问题  1.问题描述:生产者-消费者模型描述的是有一群生产者进程在生产产品,并将这些产品提供给消费...
  • 操作系统中的同步和异步

    万次阅读 多人点赞 2018-07-12 11:23:38
    操作系统同步、异步性概念 首先我们从操作系统的发展中学习什么是异步性。在操作系统发展的初期阶段,CPU处理的是作业,而且是单道批处理。什么意思呢?就是一个作业从提交到结束,程序员都不能干预,此时整台...
  • 知识总结: 1.生产者消费者模型: (同步+互斥模式)
  • 允许对个进程同属进行读取一个共享对象,因此读操作不会造成数据数据文件的混乱,但不允许reader,writer进行同时对共享文件的访问,因为这种访问会造成文件的数据混乱。所谓读者-写者问题。 读者-写者问题中,读者...
  • 总共有 读入、执行、打印 三个进程,试用PV操作描述读入B1打印B2的同步过程。 问题解读: 这个问题就是说了这样一件事:一个输入B1,被操作之后,成为B2,将B2打印。怎样用PV操作来说这件事。那么新的问题来了:啥...
  • 一座小桥(最多只能承重两个人)横跨南北两岸,任意时刻同一方向只...试 用信号灯和PV操作写出南、北两岸过桥的同步算法。 求这道题的详解,同步和互斥资源的说明。看了书上的相关内容还是不懂,希望有人帮我解答,谢谢!
  • 操作系统中进程同步问题的几个经典问题与解答

    万次阅读 多人点赞 2018-03-21 14:44:21
    1、用记录型信号量解决以下问题,用类C语言编写进程同步算法。司机 P1 售票员 P2 REPEAT REPEAT 启动 关门 正常运行 售票 到站停 开门 UNTIL FALSE UNTIL FALSE semaphore s1,s2;...
  • 操作系统】进程同步实验

    千次阅读 2019-11-29 20:11:18
    文章目录实验目的实验内容实验原理实验准备实现步骤相关函数...分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者与消费者问题的模拟,进一步加深对进程同步与互斥的理解。 实验内容 用...
  • 操作系统经典问题】理发师问题

    千次阅读 多人点赞 2019-03-31 13:02:56
    理发师问题描述如下: 理发店包含一间接待室和一间工作室,有一名理发师,接待室内有n(n≥1)把椅子,而工作室只有1把椅子。如果没有顾客,理发师就去睡觉;如果理发师在睡觉;则顾客会唤醒他;如果理发师在忙且接待...
  • 桌上有一空盘,允许存放一个水果。爸爸可向盘中放苹果,也可向盘中放桔子, 儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。...请用P、v原语实现爸爸、儿子、女儿三个并发进程的同步。 分析 ...
  • 操作系统——进程同步与互斥

    千次阅读 2022-03-22 09:19:30
    进程的同步与互斥 (1)进程同步 (2)进程互斥 1.逻辑简要: 2.四个原则: 总结: 2.3.2 进程互斥的硬件实现方法 1.中断屏蔽方法 2.TestAndSet指令 3.Swap指令 总结: ...
  • 操作系统5————进程同步经典问题:司机售票员&amp;amp;amp;amp;amp;问题生产者消费者问题&amp;amp;amp;amp;amp;哲学家进餐问题&amp;amp;amp;amp;amp;读者写者问题 一. 目录 操作系统...
  • 操作系统实验报告-基于线程的编程技术一、实验目的和要求二、实验方法与步骤(需求分析、算法设计思路、流程图等)三、实验原始纪录(源程序、数据结构等)四、实验结果及分析(计算过程与结果、数据曲线、图表等)...
  • 一、生产者-消费者问题 问题描述: 一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区 只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待 只有缓冲区不为空,消费者才能从中取出产品...
  • 操作系统同步与互斥关系

    千次阅读 2019-04-05 15:11:58
    互斥是一种制约关系,当一个进程或者多个进程进入临界区后会进行加锁操作,此时其他进程(线程)无法进入临界区,只有当该进程(线程)使用后进行解锁其他人才可以使用,这种技术往往是通过阻塞完成。 总结: 互斥...
  • 操作系统同步与异步问题

    千次阅读 2018-07-27 19:23:46
    操作系统同步和异步问题具有一定的抽象性。 同步: 一台计算机工作时会产生若干个进程任务,当这些任务同步执行,在宏观上*就像这些任务在同时运行,在微观上是这些进程分别占用一个很短的时间段交替执行。当...
  • 操作系统: 司机与售票员的进程同步问题

    万次阅读 多人点赞 2019-12-24 07:13:32
    司机与售票员的进程同步问题 在公共汽车上,司机和售票员的工作流程如图所示。 为保证乘客的安全,司机和售票员应 密切配合协调工作。 请用信号量来实现司机与售票员之间的同步。 司机 启动车辆 正常行车 ...
  • 在前操作之后对同步信号量执行V操作 在后操作之前对同步信号量执行P操作 注意: 前操作指的就是需要先进行的操作,比如:当缓冲区已满的时候,消费者先取走缓冲区的产品,生产者才能生产产品放入缓冲区。这里的...
  • 操作系统实验:实现进程同步与互斥——生产者/消费者问题
  • 不同Docker操作系统的时区同步

    千次阅读 2020-07-01 10:57:03
    我们经常会发现docker和宿主机的时间是不同步的,这几乎是个坑,特别是数据库系统,时间错误简直要命。这时间一般是相差8小时,因我们的时间是东八区时间,而docker用的是标准时间: CST是指(China Shanghai Time...
  • 同步机制应该遵循哪些准则? 空闲让进,忙则等待,有限等待,让权等待 为什么各进程对临界资源的访问必须是互斥? 临界资源指的是每次只允许一个进程进行访问的软硬件资源,故必须互斥访问。 如何保证各进程互斥访问...
  • PV操作解决进程同步问题,生产者消费者问题为例

    千次阅读 多人点赞 2019-07-08 19:49:23
    进程同步:多个进程执行过程中,为了共享资源和相互合作而在执行次序上的协调。 同时也说一下互斥:当某一进程访问某一资源时,不允许其他进程同时访问,这种限制称为互斥。 临界资源:一次只允许一个进程访问的资源...
  • 同步与互斥的区别与联系很多人不知道同步和互斥有什么区别(包括以前的我)。其实同步和互斥也是有很大联系的: 互斥:是指散布在不同进程(线程)之间的若干程序片断,当某个进程(线程)运行其中一个程序片段时,...
  • 王道考研 操作系统 第二章

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,167,472
精华内容 466,988
关键字:

操作系统经典同步问题