精华内容
下载资源
问答
  • 生产者与消费者问题
    千次阅读
    2018-05-24 21:00:46

    生产者与消费者问题是多线程中非常经典的线程同步问题,这些线程必须按照一定的生产率和消费率来访问共享缓冲区。

    实现方法是:设置两个信号量full和empty,其中full表示消费缓冲区的个数,empty表示生产缓冲区的个数,初始时没有生产物品,所以full值为0,empty值为n(n表示最大生产数量)。当生产者生产时,需要等待进入生产缓冲区,然后生产物品,生产完成后将消费缓冲区+1;当消费者消费时,需要等待进入消费缓冲区,然后消费物品,消费完成后将生产缓冲区+1;其实现代码如下:

    #include <windows.h>
    #include <iostream>
    using namespace std;
    
    //创建生产、消费信号量
    HANDLE s_full = CreateSemaphore(NULL, 0, 1, NULL);
    HANDLE s_empty = CreateSemaphore(NULL, 1, 1, NULL);
    //创建互斥量
    HANDLE mutex = CreateMutex(NULL, false, NULL);
    
    //生产者线程
    DWORD WINAPI Producer(LPVOID plParamter)
    {
    	int *k = (int*)plParamter;
    	for (int i = 0; i < 100; i++)
    	{
    		//等待空的缓冲区域
    		WaitForSingleObject(s_empty, INFINITE);
    		//等待进入临界区
    		//WaitForSingleObject(mutex, INFINITE);
    
    		//进行生产
    		(*k)++;
    		cout << "produce:" << *k << endl;
    
    		//退出临界区
    		//ReleaseMutex(mutex);
    		//消费缓冲区+1
    		ReleaseSemaphore(s_full, 1, NULL);
    
    		Sleep(500);
    	}
    	return 0L;
    }
    
    DWORD WINAPI Consumer(LPVOID plParamter)
    {
    	int *k = (int*)plParamter;
    	for (int i = 0; i < 100; i++)
    	{
    		//等待消费的缓冲区域
    		WaitForSingleObject(s_full, INFINITE);
    		//等待进入临界区
    		//WaitForSingleObject(mutex, INFINITE);
    
    		//进行消费
    		cout << "comsume:" << (*k) << endl;
    
    		//退出临界区
    		//ReleaseMutex(mutex);
    		//空缓冲区+1
    		ReleaseSemaphore(s_empty, 1, NULL);
    
    		Sleep(500);
    	}
    	return 0L;
    }
    
    int main()
    {
    	int k = 0;
    	{
    		//创建生产者进程
    		HANDLE h1 = CreateThread(NULL, 0, Producer, (void*)&k, NULL, NULL);
    		//创建消费者进程
    		HANDLE h2 = CreateThread(NULL, 0, Consumer, (void*)&k, NULL, NULL);
    		//关闭进程句柄,释放资源
    		CloseHandle(h1);
    		CloseHandle(h2);
    	}
    	Sleep(50000);
    	return 0;
    }

    更多相关内容
  • 文章目录一、生产者消费者问题概述二、生产者消费者模型优点三、生产者消费者模型变量定义四、生产者消费者流程图五、代码 一、生产者消费者问题概述 描述:俩个或者更多的线程共享同一个缓冲区,其中一个或多个...


    一、生产者消费者问题概述

    描述:俩个或者更多的线程共享同一个缓冲区,其中一个或多个线程作为“生产者”会不断地向缓冲区中添加数据,另一个或者多个线程作为“消费者”从缓冲区中取走数据。要注意以下几点:

    • 生产者和消费者必须互斥的使用缓冲区
    • 缓冲区空时,消费者不能读取数据
    • 缓冲区满时,生产者不能添加数据

    二、生产者消费者模型优点

    1、解耦:因为多了一个缓冲区,所以生产者和消费者并不直接相互调用,这样生产者和消费者的代码发生变化,都不会对对方产生影响。这样其实就是把生产者和消费者之间的强耦合解开,变成了生产者和缓冲区,消费者和缓冲区之间的弱耦合

    2、支持并发:如果消费者直接从生产者拿数据,则消费者需要等待生产者生产数据,同样生产者需要等待消费者消费数据。

    而有了生产者 / 消费者模型,生产者和消费者可以是俩个独立的并发主体。生产者把制造出来的数据添加到缓冲区,就可以去生产下一个数据了。

    而消费者也是一样的,从缓冲区中读取数据,不需要等待生产者。这样,生产者和消费者就可以并发的执行。

    3、支持忙闲不均:如果消费者直接从生产者这里拿数据,而生产者生产数据很慢,消费者消费数据很快,或者生产者产生数据很多,消费者消费数据很慢。都会造成占用CPU的时间片白白浪费。

    生产者 / 消费者模型中,生产者只需要将生产的数据添加到缓冲区,缓冲区满了就不生产了。消费者从缓冲区中读取数据,缓冲区空了就不消费了,使得生产者/消费者的处理能力达到一个动态的平衡。

    三、生产者消费者模型变量定义

    定义 :
    sem_empty (代表缓冲区有无空闲)来判断生产者能否往缓冲区写数据  初值为 N

    sem_full (代表缓冲区有几个数据)来判断消费者能否从缓冲区读数据   初值为0

    因为生产者在往缓冲区写数据时,消费者不能读,所以就需要定义一个互斥锁 mutex

    四、生产者消费者流程图

    在这里插入图片描述
    生产者:
    顺序不能更改
    在这里插入图片描述
    消费者:
    在这里插入图片描述

    五、代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<pthread.h>
    #include<semaphore.h>
    
    #define BUFF_MAX 10
    #define SC_NUM 2
    #define XF_NUM 3
    
    int buff[BUFFMAX];
    int in = 0;
    int out = 0;
    
    sem_t sem_empty;//信号量
    sem_t sem_full;//信号量
    pthread_mutex_t mutex;
    
    void *sc_thread(coid *arg)
    {
    	int index = (int)arg;
    	for(int i = 0; i < 30; i++)
    	{
    		sem_wait(&sem_empty);//看有没有空闲位置,p减一
    		pyhread_mutex_lock(&mutex);//加锁
    		buff[in] = rand() % 100;
    		printf("第%d个线程产生数据:%d,在%d的位置\n",index,buff[in],in);
    		in = (in + 1) % BUFF_MAX;
    		 pthread_mutex_unlock(&mutex);
    		 sem_post(&sem_full);//数据的个数 v加一
    			
    		
    	}
    }
    
    void * xf_thread(void *arg)
    {
    	int index = (int)arg;
    	for(int i = 0;i < 20; i++)
    	{
    		sem_wait(&sem_full);
    		pthread_mutex_lock(&mutex);
    		printf("---------第%d个线程,消费数据:%d,在%d位置\n",index,buff[out],out);
    		out = (out + 1) % BUFF_MAX;
    		pthread_mutex_unlock(&mutex);
    		sem_post(&sem_empty);
    	}
    }
    
    int main()
    {
    	sem_init(&sem_empty,0,0,BUFF_MAX);//信号量初始化
    	sem_init(&sem_full,0,0);//信号量初始化
    	pthread_mutex_init(&mutex,NULL);
    	
    	srand((int))time(NULL);
    	
    	pthread_t sc_id[SC_NUM];//定义生产者
    	pthread_t xf_id[XF_NUM];//定义消费者
    
    	for(int i = 0;i < SC_NUM;i++)
    	{
    		pthread_create(	&sc_id[i],NULL,sc_thread,(void*)i);//创建生产者
    	}
    
    	for(int i = 0; i < XF_NUM; i++)
    	{
    		pthread_create(&xf_id[i],NULL,xf_thread,(void*)i);//创建消费者
    	}
    	
    	for(int i = 0;i < SC_NUM;i++)
    	{
    		pthread_join(&sc_id[i],NULL);
    	}
    
    	for(int i = 0; i < XF_NUM; i++)
    	{
    		pthread_join(&xf_id[i],NULL);
    	}
    	
    	//销毁信号量
    	sem_destroy(&sem_empty);
    	sem_destrory(&sem_full);
    
    	//互斥锁销毁
    	pthread_mutex_destroy(&mutex);
    		
    	printf("main over\n");
    	exit(0);
    }
    
    展开全文
  • 学过操作系统的我们一定都听老师讲过一个经典的问题——生产者消费者问题。这一节我们就借助Java中的多线程来理解一下这个问题问题描述 假定我们定义一个生产者和一个消费者,生产者生产一个物品放入仓库,消费...

    问题背景

    学过操作系统的我们一定都听老师讲过一个经典的问题——生产者消费者问题。这一节我们就借助Java中的多线程来理解一下这个问题。


    问题描述

    假定我们定义一个生产者和一个消费者,生产者生产一个物品放入仓库,消费者从仓库消费一个物品。

    下面我们通过代码简单演示一下这个过程,我们新建示例代码如下:
    请添加图片描述
    高清图片,打开看代码,节省文章位置!
    请添加图片描述

    运行程序代码时,你会发现有可能出现下面的这些情况:

    这些情况都是在我们模拟的场景中不应该出现的,下面我们分析产生这个问题的原因。

    请添加图片描述

    原因分析:

    产生的原因其实还是由于上一节的多线程的问题造成的,因为线程占用CPU的资源是随机的。具体的请看上一节的开始讲到的。下面我们使用流程图来分析问题:

    未对生产和消费过程进行干涉的过程:
    请添加图片描述

    对生产和消费过程添加互斥锁:
    请添加图片描述
    这时候我们运行程序,此时又会产生另一个问题,我们的程序会卡在某一个位置不动,我们称这种情况为死锁。

    计算机系统中,如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。

    在两个或多个任务中,如果每个任务锁定了其他任务试图锁定的资源,此时会造成这些任务永久阻塞,从而出现死锁。例如:事务A 获取了行 1 的共享锁。事务 B 获取了行 2 的共享锁。


    解决方案:

    在我们的程序中就是因为我们引入互斥锁导致了生产者和消费者竞争资源,解决的办法很简单,我们使用notifyAll();在生产者生产完成和消费者消费完成后唤醒所有的线程。
    请添加图片描述


    解决问题:

    请添加图片描述

    总结;

    看到这可能很多人觉得我这讲了跟没讲一样,其实不是,因为学过的都知道,操作系统的知识老师在课上讲解的时候都是再说文字,对于这个概念来说大多数人都是一知半解的,这里我没有用一些刻板的文字去解释,而是选择一个经典案例,结合简单的代码复现和流程分析,将抽象的问题形象化,希望大家能通过这些理解生产者消费者问题。

    展开全文
  • 生产者与消费者问题C语言实现

    万次阅读 多人点赞 2018-05-27 10:51:24
    生产者消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。缓冲池被占用时,...

    实验目的
    ①实现生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。缓冲池被占用时,任何进程都不能访问。

    ②每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。

    实验原理
    在同一个进程地址空间内执行两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻挡,直到新的物品被生产出来。

    生产者流程图
    这里写图片描述
    消费者流程图
    这里写图片描述
    注意点
    ①本次实验是关于生产者与消费者之间互斥和同步的问题。问题的是指是P、V操作,实验设一个共享缓冲区,生产者和消费者互斥的使用,当一个线程使用缓冲区的时候,另一个让其等待直到前一个线程释放缓冲区为止。
    ②生产者与消费者是一个与现实有关的经验问题,通过此原理举一反三可以解决其他类似的问题。 通过本实验设计,我们对操作系统的P、V进一步的认识,深入的了解P、V操作的实质和其重要性。课本的理论知识进一步阐述了现实中的实际问题。
    ③Linux环境下编写变异C语言有Windows稍有不同,注意在Linux中编译带有线程

    #include <stdio.h>
    #include <pthread.h>
    #include <windows.h>
    #define N 100
    #define true 1
    #define producerNum  10
    #define consumerNum  5
    #define sleepTime 1000
    
    typedef int semaphore;
    typedef int item;
    item buffer[N] = {0};
    int in = 0;
    int out = 0;
    int proCount = 0;
    semaphore mutex = 1, empty = N, full = 0, proCmutex = 1;
    
    void * producer(void * a){
        while(true){
            while(proCmutex <= 0);
            proCmutex--;
            proCount++;
            printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);
            proCmutex++;
    
            while(empty <= 0){
                printf("缓冲区已满!\n");
            }
            empty--;
    
            while(mutex <= 0);
            mutex--;
    
            buffer[in] = proCount;
            in = (in + 1) % N;
    
            mutex++;
            full++;
            Sleep(sleepTime);
        }
    }
    
    void * consumer(void *b){
        while(true){
            while(full <= 0){
                printf("缓冲区为空!\n");
            }
            full--;
    
            while(mutex <= 0);
            mutex--;
    
            int nextc = buffer[out];
            buffer[out] = 0;//消费完将缓冲区设置为0
    
            out = (out + 1) % N;
    
            mutex++;
            empty++;
    
            printf("\t\t\t\t消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
            Sleep(sleepTime);
        }
    }
    
    int main()
    {
        pthread_t threadPool[producerNum+consumerNum];
        int i;
        for(i = 0; i < producerNum; i++){
            pthread_t temp;
            if(pthread_create(&temp, NULL, producer, NULL) == -1){
                printf("ERROR, fail to create producer%d\n", i);
                exit(1);
            }
            threadPool[i] = temp;
        }//创建生产者进程放入线程池
    
    
        for(i = 0; i < consumerNum; i++){
            pthread_t temp;
            if(pthread_create(&temp, NULL, consumer, NULL) == -1){
                printf("ERROR, fail to create consumer%d\n", i);
                exit(1);
            }
            threadPool[i+producerNum] = temp;
        }//创建消费者进程放入线程池
    
    
        void * result;
        for(i = 0; i < producerNum+consumerNum; i++){
            if(pthread_join(threadPool[i], &result) == -1){
                printf("fail to recollect\n");
                exit(1);
            }
        }//运行线程池
        return 0;
    }

    这里写图片描述
    更多内容访问omegaxyz.com
    网站所有代码采用Apache 2.0授权
    网站文章采用知识共享许可协议BY-NC-SA4.0授权
    © 2018 • OmegaXYZ-版权所有 转载请注明出处

    展开全文
  • 实验四、生产者消费者问题(15分) • 一个大小为3的缓冲区,初始为空 • 2个生产者 – 随机等待一段时间,往缓冲区添加数据, – 若缓冲区已满,等待消费者取走数据后再添加 – 重复6次 • 3个消费者 – 随机...
  • [进程同步]—生产者与消费者问题

    千次阅读 多人点赞 2018-11-03 15:41:29
    生产者与消费者问题 PV操作是用来操作信号量的。 P:等待——wait——减法作用——阻塞作用 V:释放——signal——加法作用——唤醒作用 S.value &gt; 0 :有空闲CPU; S.value = 0...
  • 关于生产者与消费者的问题,百度百科上的定义是这样的:生产者消费者问题,也称有限缓冲问题,是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在...
  • 操作系统生产者与消费者问题代码实现

    万次阅读 多人点赞 2019-05-14 02:23:41
    问题分析: ①假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就...在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。他们之间也存在互斥,即生产者...
  • 一、生产者消费者问题 生产者和消费者问题是计算机同步互斥的经典问题,其意思就是生产者把生产出来的产品放在仓库里,消费者把产品从仓库里取出来。仓库属于临界区,生产者和消费者一次只能一个进入临界区中。两个...
  • 进程的互斥与同步——生产者与消费者问题

    千次阅读 多人点赞 2019-11-07 14:39:18
    利用Windows提供的API函数,编写程序,解决生产者与消费者问题,实现进程的互斥与同步。 实验步骤与内容 进程的互斥与同步。编写一段程序,模拟生产者消费者线程,实现进程的互斥与同步。 利用VC++6.0实现上述...
  • 互斥:保证一个资源只能被一个进程使用。 首先,解释“321”: 1、一个交易场所(缓冲区,类似于超市) ... 消费者与消费者互斥 生产者与消费者同步与互斥 在未做任何处理之前让生产者生产数据,消费者消费数
  • Disruptor是一个开源的JAVA框架,它被设计用于在生产者消费者(producer-consumer problem,简称PCP)问题上获得尽量高的吞吐量(TPS)和尽量低的延迟。Disruptor是LMAX在线交易平台的关键组成部分,LMAX平台使用...
  • 进程同步问题——生产者消费者问题 问题梗概 生产者消费者问题是相互合作关系的进程关系的一种抽象,是一个广义的概念,可以代表一类具有相同属性的进程 生产者:一个或者是多个生产者将生产的数据存入缓冲区中...
  • 【JAVA多线程】如何解决一个生产者与消费者问题

    万次阅读 多人点赞 2018-11-01 15:28:19
    如何解决一个生产者与消费者问题 生产者与消费者问题是多线程同步的一个经典问题生产者消费者同时使用一块缓冲区,生产者生产商品放入缓冲区,消费者从缓冲区中取出商品。我们需要保证的是,当缓冲区满时,生产...
  • 《操作系统》-生产者消费者问题

    千次阅读 2022-02-12 12:47:22
    什么是生产者消费者问题? 系统中有一组生产者进程和一组消费者进程。生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个进程并使用,那么他们之间具有这样一层关系 生产者、消费者共享一个...
  • 操作系统:使用临界区和互斥量两种方法实现简单生产者与消费者问题
  • 生产者与消费者问题是并发编程里面的经典问题,下面用wait()和notify()来实现消费者线程和生产者线程的并发执行。  说之前先讲几个概念:  wait()与sleep()的区别:  1.首先sleep()是Thread()类的方法,而...
  • 在说到进程的同步的问题上,毫无疑问,生产者与消费者这个经典问题是不可避免的。   生产者生产的前提是:生产者生产出来的产品容器还能够装下,否则等待消费者消费; 消费者消费的前提是:容器中有产品能够让...
  • Java多线程——生产者消费者问题

    千次阅读 2022-01-19 11:57:49
    生产者消费者问题(英语:Producer-consumer problem)就是典型的多线程同步案例,它也被称为有限缓冲问题(英语:Bounded-buffer problem)。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和...
  • 生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将...
  • 生产者与消费者问题又称为有界缓冲区问题 场景: 一个或者多个生产者生产某种类型的数据放置在缓冲区中 有消费者从缓冲区中取数据,每次取一项 只能有一个生产者消费者对缓冲区进行操作 ...
  • 生产者消费者问题详解

    千次阅读 2017-02-17 19:25:18
    定义生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者...
  • 信号量与生产者消费者问题

    万次阅读 多人点赞 2017-01-19 15:06:44
    生产者—消费者问题 生产者—消费者题型在各类考试(考研、程序员证书、程序员面试笔试、期末考试)很常见,原因之一是生产者...生产者—消费者题型最基本的是有界缓冲区的生产者消费者问题和无界缓冲区的生产者消费者
  • 经典生产者-消费者问题解析

    千次阅读 2020-04-09 14:35:33
    1.生产者-消费者问题 生产者消费者问题在现实系统中是很普遍的。例如在一个多媒体系统中,生产者编码视频帧,而消费者消费(解码)视频帧,缓冲区的目的就是减少视频流的抖动。又如在图形用户接口设计中,生产者...
  •   以生产者消费者问题为例,学习并熟悉Linux下进程通信、同步机制的具体实现方法,主要是了解并掌握信号量机制和共享内存的使用方法,进一步熟悉Linux系统的相关指令的调用。 【实验内容】   使用共享内存和...
  • 多线程解决生产者与消费者问题

    千次阅读 2016-09-03 23:07:06
    生产者消费者问题是一个很有名的线程同步问题,以前学操作系统时,没怎么搞懂,直到现在学java学到多线程这一块才搞懂。该问题描述的是两个共享固定大小的缓冲区的线程问题。生产者的主要作用是生成一定量的数据放到...
  • 假设仓库中只能存放一件产品,生产者将生产出的产品放入仓库,消费者将仓库的中的产品取走。 仓库中没有产品,生产者将产品放入仓库,否则停止生成并等待,直到仓库中的产品被消费者取走 仓库中存放产品,消费者将...
  • 操作系统实验:实现进程同步互斥——生产者/消费者问题
  • 1、生产者在while循环里不停地生产“产品”,每生产一个,就交给店员,店员就得到一个产品 2、消费者在while循环里不停地消费产品,每消费一个,店员就移走一个产品 3、店员手里的产品少于20个,就从生产者那里拿...
  • Java线程——生产者与消费者问题

    千次阅读 2021-01-17 23:11:14
    生产者与消费者问题 等待唤醒机制其实就是经典的“生产者与消费者”的问题。 该模式在现实生活中很常见,在项目开发中也广泛应用,它是线程间通信的经典应用。 生产者是一堆线程,消费者是另一堆线程,内存缓冲区...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 396,112
精华内容 158,444
关键字:

生产者与消费者问题

友情链接: GSethvdc20mw.rar