精华内容
下载资源
问答
  • 本文是对网上答复做的补充说明,那位回答者说的其实很...有关(在生产者消费者问题中,如果将P操作位置互换,会产生什么结果)问题的答复,网址如下: https://zhidao.baidu.com/question/277301144.html?qbl=relate

    本文是对网上答复做的补充和修改,变动很大,对很多内容是持有相反观点的,并对一些内容进行了解释,这样使整个过更加清晰些,不为奖励,只为和我一样在理解很浅时的同学解惑。字可能很多,但我希望你读完,尤其是你一头雾水时。

    生产者

    While(true){ 

        ​生产一件产品;

        ​P(full);

        ​P(mutex);

        ​放入一件产品;

        ​V(mutex);

        ​V(empty);

    }

    消费者

    While(true){ 

        ​P(empty);

        ​P(mutex);

        ​取出一件产品;

        ​消费一件产品;

        ​V(mutex);

        ​V(full);

    }

    假设一种情况(缓冲区满的情况),则:full=5,empty=0,mutex=1

    在生产者—消费者问题中,如果将两个P操作,即P(full)和P(mutex)互换位置,或者P(empty)和P(mutex)互换位置,都可能引起死锁。

    考虑系统中缓冲区全满,若一生产者进程先执行了P(mutex)操作并获得成功,当消费者执行完P(empty)操作接着执行P(mutex)时,它(消费者)将因失败而进入阻塞状态

    虽然empty本身初值就为0,但是在缓冲区满时,empty就应该变为满但是对缓冲区的操作就是对临界资源的操作,是互斥的,这时生产者还在因为缓冲区满生产东西了东西而放不入缓冲区 ,阻塞在p(full)操作。导致无法V(mutex)这是一个消费者跟生产者互斥操作临界资源阶段,有些同学可能会理解错  “这里说的跟那位答题者不太一样,我认为他把缓冲区满的条件加上了,但没改消费客可同步消费的数量”)

    ,它(消费者)期待生产者执行V(mutex)来唤醒自己。但是在此之前,(生产者)它不可能执行V(mutex)操作,从而使企图通过P(mutex)进入自己的临界区的其他生产者和所有的消费者进程全部进入阻塞状态

    消费者一直在等待V(mutex)的唤醒/释放,生产者因为缓冲区满而一直等待消费者取走物品),从而引起系统死锁。

     

    通俗的话来讲:生产者卡在放不进去东西,消费者因为生产者放不进去东西,也就是对临界资源的操作一直无法完成而互斥,导致所有消费者,和其他生产者卡在P(mutex)无法对临界资源操作

    类似地,消费者两个P操作互换。在缓冲区为空时,消费者进程先执行P(mutex),然后会卡在P(empty),生产者后执行P(mutex)时会因为对临界资源操作的互斥而卡住。也成了死锁。

    V(full)和V(mutex)互换位置,或者V(empty)和V(mutcx)互换位置,则不会引起死锁,其影响只是使临界资源的释放略为推迟一些。

    有关网上关于(在生产者和消费者问题中,如果将P操作位置互换,会产生什么结果)问题的答题者的答复网址如下(可以和本文对比来看)

    https://zhidao.baidu.com/question/277301144.html?qbl=relate_question_1&word=%B2%D9%D7%F7%CF%B5%CD%B3%B6%E0%C9%FA%B2%FA%D5%DF%B6%E0%CF%FB%B7%D1%D5%DFP%28S1%29%2C%20P%28M%29%20%C4%DC%BB%A5%BB%BB%C2%F0%3F&hideOtherAnswer=true&newAnswer=1

    (侵删)

    展开全文
  • 秒杀线程第十篇 生产者消费者问题

    万次阅读 多人点赞 2012-05-21 10:18:09
    生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有个缓冲区的缓冲池,生产者将...

        继经典线程同步问题之后,我们来看看生产者消费者问题及读者写者问题。生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。

        这个生产者消费者题目不仅常用于操作系统的课程设计,也常常在程序员和软件设计师考试中出现。并且在计算机考研的专业课考试中也是一个非常热门的问题。因此现在就针对这个问题进行详细深入的解答。

     

        首先来简化问题,先假设生产者和消费者都只有一个,且缓冲区也只有一个。这样情况就简便多了。

        第一.从缓冲区取出产品和向缓冲区投放产品必须是互斥进行的。可以用关键段互斥量来完成。

        第二.生产者要等待缓冲区为空,这样才可以投放产品,消费者要等待缓冲区不为空,这样才可以取出产品进行消费。并且由于有二个等待过程,所以要用二个事件信号量来控制。

        考虑这二点后,代码很容易写出来。另外为了美观起见,将消费者的输出颜色设置为彩色,有关如何在控制台下设置彩色输出请参阅《VC 控制台颜色设置》。

    //1生产者 1消费者 1缓冲区
    //使用二个事件,一个表示缓冲区空,一个表示缓冲区满。
    //再使用一个关键段来控制缓冲区的访问
    #include <stdio.h>
    #include <process.h>
    #include <windows.h>
    //设置控制台输出颜色
    BOOL SetConsoleColor(WORD wAttributes)
    {
    	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (hConsole == INVALID_HANDLE_VALUE)
    		return FALSE;	
    	return SetConsoleTextAttribute(hConsole, wAttributes);
    }
    const int END_PRODUCE_NUMBER = 10;   //生产产品个数
    int g_Buffer;                        //缓冲区
    //事件与关键段
    CRITICAL_SECTION g_cs;
    HANDLE g_hEventBufferEmpty, g_hEventBufferFull;
    //生产者线程函数
    unsigned int __stdcall ProducerThreadFun(PVOID pM)
    {
    	for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
    	{
    		//等待缓冲区为空
    		WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
    
    		//互斥的访问缓冲区
    		EnterCriticalSection(&g_cs);
    		g_Buffer = i;
    		printf("生产者将数据%d放入缓冲区\n", i);
    		LeaveCriticalSection(&g_cs);
    		
    		//通知缓冲区有新数据了
    		SetEvent(g_hEventBufferFull);
    	}
    	return 0;
    }
    //消费者线程函数
    unsigned int __stdcall ConsumerThreadFun(PVOID pM)
    {
    	volatile bool flag = true;
    	while (flag)
    	{
    		//等待缓冲区中有数据
    		WaitForSingleObject(g_hEventBufferFull, INFINITE);
    		
    		//互斥的访问缓冲区
    		EnterCriticalSection(&g_cs);
    		SetConsoleColor(FOREGROUND_GREEN);
    		printf("  消费者从缓冲区中取数据%d\n", g_Buffer);
    		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    		if (g_Buffer == END_PRODUCE_NUMBER)
    			flag = false;
    		LeaveCriticalSection(&g_cs);
    		
    		//通知缓冲区已为空
    		SetEvent(g_hEventBufferEmpty);
    
    		Sleep(10); //some other work should to do
    	}
    	return 0;
    }
    int main()
    {
    	printf("  生产者消费者问题   1生产者 1消费者 1缓冲区\n");
    	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
    
    	InitializeCriticalSection(&g_cs);
    	//创建二个自动复位事件,一个表示缓冲区是否为空,另一个表示缓冲区是否已经处理
    	g_hEventBufferEmpty = CreateEvent(NULL, FALSE, TRUE, NULL);
    	g_hEventBufferFull = CreateEvent(NULL, FALSE, FALSE, NULL);
    	
    	const int THREADNUM = 2;
    	HANDLE hThread[THREADNUM];
    	
    	hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
    	hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
    	WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
    	CloseHandle(hThread[0]);
    	CloseHandle(hThread[1]);
    	
    	//销毁事件和关键段
    	CloseHandle(g_hEventBufferEmpty);
    	CloseHandle(g_hEventBufferFull);
    	DeleteCriticalSection(&g_cs);
    	return 0;
    }

    运行结果如下所示:

    可以看出生产者与消费者已经是有序的工作了。

     

        然后再对这个简单生产者消费者问题加大难度。将消费者改成2个,缓冲池改成拥有4个缓冲区的大缓冲池。

        如何来思考了这个问题了?首先根据上面分析的二点,可以知道生产者和消费者由一个变成多个的影响不大,唯一要注意的是缓冲池变大了,回顾一下《秒杀多线程第八篇 经典线程同步 信号量Semaphore》中的信号量,不难得出用二个信号量就可以解决这种缓冲池有多个缓冲区的情况——用一个信号量A来记录为空的缓冲区个数,另一个信号量B记录非空的缓冲区个数,然后生产者等待信号量A,消费者等待信号量B就可以了。因此可以仿照上面的代码来实现复杂生产者消费者问题,示例代码如下:

    //1生产者 2消费者 4缓冲区
    #include <stdio.h>
    #include <process.h>
    #include <windows.h>
    //设置控制台输出颜色
    BOOL SetConsoleColor(WORD wAttributes)
    {
    	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (hConsole == INVALID_HANDLE_VALUE)
    		return FALSE;
    	
    	return SetConsoleTextAttribute(hConsole, wAttributes);
    }
    const int END_PRODUCE_NUMBER = 8;  //生产产品个数
    const int BUFFER_SIZE = 4;          //缓冲区个数
    int g_Buffer[BUFFER_SIZE];          //缓冲池
    int g_i, g_j;
    //信号量与关键段
    CRITICAL_SECTION g_cs;
    HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;
    //生产者线程函数
    unsigned int __stdcall ProducerThreadFun(PVOID pM)
    {
    	for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
    	{
    		//等待有空的缓冲区出现
    		WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);
    
    		//互斥的访问缓冲区
    		EnterCriticalSection(&g_cs);
    		g_Buffer[g_i] = i;
    		printf("生产者在缓冲池第%d个缓冲区中投放数据%d\n", g_i, g_Buffer[g_i]);
    		g_i = (g_i + 1) % BUFFER_SIZE;
    		LeaveCriticalSection(&g_cs);
    
    		//通知消费者有新数据了
    		ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
    	}
    	printf("生产者完成任务,线程结束运行\n");
    	return 0;
    }
    //消费者线程函数
    unsigned int __stdcall ConsumerThreadFun(PVOID pM)
    {
    	while (true)
    	{
    		//等待非空的缓冲区出现
    		WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);
    		
    		//互斥的访问缓冲区
    		EnterCriticalSection(&g_cs);
    		SetConsoleColor(FOREGROUND_GREEN);
    		printf("  编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), g_j, g_Buffer[g_j]);
    		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    		if (g_Buffer[g_j] == END_PRODUCE_NUMBER)//结束标志
    		{
    			LeaveCriticalSection(&g_cs);
    			//通知其它消费者有新数据了(结束标志)
    			ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
    			break;
    		}
    		g_j = (g_j + 1) % BUFFER_SIZE;
    		LeaveCriticalSection(&g_cs);
    
    		Sleep(50); //some other work to do
    
    		ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);
    	}
    	SetConsoleColor(FOREGROUND_GREEN);
    	printf("  编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());
    	SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    	return 0;
    }
    int main()
    {
    	printf("  生产者消费者问题   1生产者 2消费者 4缓冲区\n");
    	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
    
    	InitializeCriticalSection(&g_cs);
    	//初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.
    	g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);
    	g_hSemaphoreBufferFull  = CreateSemaphore(NULL, 0, 4, NULL);
    	g_i = 0;
    	g_j = 0;
    	memset(g_Buffer, 0, sizeof(g_Buffer));
    
    	const int THREADNUM = 3;
    	HANDLE hThread[THREADNUM];
    	//生产者线程
    	hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
    	//消费者线程
    	hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
    	hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
    	WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
    	for (int i = 0; i < THREADNUM; i++)
    		CloseHandle(hThread[i]);
    
    	//销毁信号量和关键段
    	CloseHandle(g_hSemaphoreBufferEmpty);
    	CloseHandle(g_hSemaphoreBufferFull);
    	DeleteCriticalSection(&g_cs);
    	return 0;
    }

    运行结果如下图所示:

    输出结果证明各线程的同步和互斥已经完成了。

     

    至此,生产者消费者问题已经圆满的解决了,下面作个总结:

    1.首先要考虑生产者与消费者对缓冲区操作时的互斥。

    2.不管生产者与消费者有多少个,缓冲池有多少个缓冲区。都只有二个同步过程——分别是生产者要等待有空缓冲区才能投放产品,消费者要等待有非空缓冲区才能去取产品。

     

    下一篇《秒杀多线程第十一篇读者写者问题》将介绍另一个著名的同步问题——读者写者问题,欢迎大家再来参阅。

     

    转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7577591

    如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。

     

    展开全文
  • 在引入生产者消费者问题前,先要介绍几个知识点 1.临界区的相关问题。临界区是指每个进程访问临界资源的那段程序。临界资源是指每次只允许一个进程的访问的资源 2.PV操作,是一种利用信号量,通过while循环来控制...

    多生产者—多消费者问题(PV操作的简单例题)

    在引入生产者消费者问题前,先要介绍几个知识点
    1.临界区的相关问题。临界区是指每个进程访问临界资源的那段程序。临界资源是指每次只允许一个进程的访问的资源
    2.PV操作,是一种利用信号量,通过while循环来控制进程的执行,以规避进程进入死锁状态

    对于多生产者多消费者问题来说,其实最根本的和单生产者单消费者问题差不多
    以下面这个例子来说明
    ■桌子上有一个盘子,每次只能放一个水果。爸爸专门向盘子中放苹果,妈妈专门放桔子,儿子等着吃盘中的桔子,女儿等着吃苹果。用P、V操作实现他们之间的同步。

    Semaphore mutex=1,apple=0,orange=0, empty=1;Begin
      Parbegin
        Father: begin
         Repeat
         准备苹果
         Wait(empty);      在确认盘中是否为空,若empty不为0,则可继续执行下面
         Wait(mutex);      在确认其他进程是否在执行,若没有,则减一,开始后续操作
         放入苹果;          生产者行为
         Signal(mutex);    释放生产者动作,允许其他进程执行
         Signal(apple);    生产者行为成功,给apple库存加一,允许后续消费apple进程执行
        Until false;
       end
    **********************************************************************
        Daughter:begin
         Repeat
         Wait(apple);      判断apple是否有有库存,若apple为0,则持续等待,否则减一并执行后续功能
         Wait(mutex);      判断是否有其他进程正在执行,若有,持续等待
         拿走苹果;          消费者行为
         Signal(mutex);    释放资源,允许其他进程进入临界区
         signal(empty);    释放资源,允许生产者进程进入临界区
        Until false;
       end
    **********************************************************************
      Parbegin
        Mother: begin
         Repeat
         准备橘子
         Wait(empty);    判断盘子是否为空,empty为1则执行下一步
         Wait(mutex);    判断当前是否有进程占用临界区
         放入橘子;        生产者行为
         Signal(mutex);  释放资源,允许其他进程进入临界区
         Signal(orange); 释放资源,允许消费者进程进入临界区
        Until false;
       end
    **********************************************************************
        Son:begin
         Repeat
         Wait(orange);    判断orange是否有有库存,若orange为0,则持续等待,否则减一并执行后续功能
         Wait(mutex);     判断是否有其他进程正在执行,若有,持续等待
         拿走橘子;         消费者行为
         Signal(mutex);   释放资源,允许其他进程进入临界区
         signal(empty);   释放资源,允许生产者进程进入临界区
        Until false;
       end
    

    多生产者多消费者问题和单生产者单消费者问题本质上是差不多的。
    生产者与消费者公用一个信号量来限制使用临界区资源
    不同的消费者与不同的生产者对各自的产品与消费对象都用一个独立的信号量来控制,避免空等和错误使用

    展开全文
  • 线程的生产者消费者问题

    千次阅读 2015-06-12 14:51:55
    线程的生产者消费者问题是比较经典的线程问题,如果知道编码解决生产者消费者问题,那么对于线程应该基本算掌握了。我不知道大家的生产者消费者问题是怎么样的(应该有几个版本吧),这里我说下我的生产...

            多线程的生产者和消费者问题是比较经典的多线程问题,如果知道编码解决生产者和消费者问题,那么对于多线程应该基本算掌握了。我不知道大家的生产者和消费者问题是怎么样的(应该有几个版本吧),这里我说下我的生产者和消费者问题:

            有多个生产线程,他们只负责生产资源;有多个消费者,同样他们只负责消费。但是他们需要满足下面条件:

            生产者:只有当资源没有的时候,生产者才开始生产,但是为了防止浪费,每次只能生产指定数量的资源。当生产者生产完足够资源时,就进入睡眠,同时叫醒消费者去消费;

            消费者:只有有资源时消费者才会去消费,当然每次消费多少可以自己设置。如果发现资源消费完了,则要马上叫生产者去生产,而消费者马上进入睡眠;

        

            涉及到的知识:线程基础知识、多线程同步、互斥量、条件变量;可以参考: linux环境编程之多线程同步


    生产者程序:

     #include<pthread.h>
     #include<stdio.h>
     #include<stdlib.h>
     #include<fcntl.h>
     
     static int source = 0;  // 定义资源为个整型数,当然也可以定义为一个结构体
     static pthread_mutex_t lock; // 定义个互斥量用来锁住资源
     static pthread_cond_t con; // 定义条件变量
     
     static pthread_t pro_t1, pro_t2, con_t1, con_t2, con_t3, con_t4;
     
     void* product(void *arg)
     {
         while(1){
             if (!pthread_mutex_lock(&lock)){
                 if (0 == source){
                     source += 3; // 每次都生产3个资源
                     sleep(1); // 为了查看打印的数据而已
                     // 查看下是哪个生产者来生产的
                     if (pro_t1 == pthread_self()) 
                         printf("\n\npro1 make source %d ==> %d\n", source-3, source);
                     else if (pro_t2 == pthread_self())
                         printf("\n\npro2 make source %d ==> %d\n", source-3, source);
                     else 
                         printf("error pro\n");
                     // 已经改变了条件,把条件变量上的等待线程都唤醒,让他们自行抢占
                     pthread_cond_broadcast(&con);
                     pthread_cond_wait(&con, &lock);// 生产者生产完休息
                 }   
                 pthread_mutex_unlock(&lock);
             }   
             usleep(500);// 为了防止总是同一个生产者去生产,也给消费者时间去消费
         }   
         return (void*)0;
     }
    

    生产者分析:

            首先进入死循环,不停的抢锁,抢到锁后查看下是否符合条件:

            不符合则解锁,等0.5秒,让其他线程去抢占(主要是让消费者抢到锁去消费)。其实这里有个问题,如果有多个生产者,而且刚好每次都是生产者得到锁,那么就是个死锁了。虽然这种可能性比较小,但是这也有可能。就算不产生死锁,也会影响性能,让不相关的线程去抢占锁(上锁 == 判断 == 解锁  会消耗时间);

            符合条件,则抢到锁的生产线程负责生产资源,生产完后留下姓名,最后叫醒消费线程去消费,自己则睡眠休息;这同样有个问题:就是生产线程会去捣乱,会去抢锁,然后判断,解锁。这会降低系统性能,后期可以想办法改进下。

            当资源条件改变后,则生产线程(上次生产的那个线程)会被叫醒,这时候锁都在他手上。然后解锁,让大家去抢锁,这里延迟了0.5秒,是不让这个线程再去抢锁了(0.5秒虽然很长,但也有可能还是上次生产的那个线程获取到了锁),同样这也有上面的问题;


    消费者程序:

    void* consume(void *arg)
     {
         while(1){
             if (!pthread_mutex_lock(&lock)){// 抢锁
                 if (source){ 
                     source--;// 消费资源
                     sleep(1);
                      // 打印谁消费了资源
                     if (con_t1 == pthread_self())
                         printf("con1 make source %d ==> %d\n", source+1, source);
                     else if (con_t2 == pthread_self())
                         printf("con2 make source %d ==> %d\n", source+1, source);
                     else if (con_t3 == pthread_self())
                         printf("con3 make source %d ==> %d\n", source+1, source);
                     else if (con_t4 == pthread_self())
                         printf("con4 make source %d ==> %d\n", source+1, source);
                     else
                         printf("error con\n");
     
                     if(!source){// 查看下资源是否还有
                         pthread_cond_broadcast(&con);// 如果没有资源了,则通知生产者开始工作了
                         pthread_cond_wait(&con, &lock);// 消费者进入睡眠等待生产者生产好资源来
                     }
                 }
                 pthread_mutex_unlock(&lock);
             }
             usleep(500);// 给生产者时间去生产,或者给其他消费者机会去获取锁去消费
         }
         return (void*)0;
     }
    消费者分析:

            和生产者类似,这里就不详细分析了。首先抢占锁,判断是否有资源,没有的话则等生产着去生产。如果有,则进入消费,消费完后再判断下是否把资源全部消耗掉了,如果没有,则让其他线程进入消费;如果有,则通知生产线程去生产,而自己休眠等待通知;


    缺陷:

            这个解决方案有两个缺陷:

            1、多生产者时,当生产完后,该生产资源的线程睡眠(同时唤醒所有消费),但其他生产线程会和消费线程抢锁。多消费者,同样的情况;

            2、开始的时候其实是没有唤醒,比如消费线程开始的时候没有资源,不是通知生产者生产(这时候生产线程也没有休眠,就算通知也没有用),而是循环等待,希望生产线程能获取到锁去生产。

    解决:

            解决方法可以试试先判断资源条件是否符合,符合进入上锁然后操作,不符合则等待睡眠。但因为条件检查和上锁不是原子操作,容易变成死锁。还有其他一些问题。后期再研究下,或者大家帮忙解决下(不过自己研究会更有乐趣,可以提供思路)


    主函数程序:

     int main(int argc, char* argv[])
     {
         pthread_attr_t attr; // 互斥量锁属性
         pthread_attr_init(&attr);// 初始化互斥量锁属性
     
         pthread_mutex_init(&lock, NULL);// 初始化互斥量锁
         pthread_cond_init(&con, NULL); // 初始化条件变量
     
         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);// 设置锁属性
     
         pthread_create(&con_t1, &attr, &consume, NULL);// 创建消费线程和生产线程
         pthread_create(&con_t2, &attr, &consume, NULL);
         pthread_create(&con_t3, &attr, &consume, NULL);
         pthread_create(&con_t4, &attr, &consume, NULL);
         pthread_create(&pro_t1, &attr, &product, NULL);
         pthread_create(&pro_t2, &attr, &product, NULL);
     
         pause();// 挂起主线程,主线程不能死
         pthread_cond_destroy(&con);// 下面都是注销函数,做扫尾工作
         pthread_mutex_destroy(&lock);
         pthread_attr_destroy(&attr);
     
         return 0;
     }

    转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/46471663


    展开全文
  • 线程解决生产者消费者问题

    千次阅读 2016-09-03 23:07:06
    生产者消费者问题是一个很有名的线程同步问题,以前学操作系统时,没怎么搞懂,直到现在学java学到线程这一块才搞懂。该问题描述的是两个共享固定大小的缓冲区的线程问题。生产者的主要作用是生成一定量的数据放到...
  • Java多种方式解决生产者消费者问题(十分详细)

    万次阅读 多人点赞 2018-08-16 08:40:50
    生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲...
  • c++线程生产者消费者问题代码

    千次阅读 2017-03-14 10:43:47
    c++线程生产者消费者问题代码
  • 生产者消费者问题

    千次阅读 2013-10-25 10:47:18
    在《UNIX网络编程 卷二》中看到了这个有关生产者消费者问题,书中指出消费者存在的意义需要看具体的应用程序。相对与生产者一个消费者问题来说,我们需要额外的同步一下不同消费者之间的竞争...
  • 生产者消费者问题-代码详解(Java线程)

    千次阅读 热门讨论 2020-06-13 11:10:07
    生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个线程同步问题的经典案例。 该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和...
  • Java线程技术~生产者消费者问题

    万次阅读 热门讨论 2020-06-16 14:15:18
    Java线程技术~生产者消费者问题 本文是上一篇文章的后续,详情点击该连接 线程通信 应用场景:生产者消费者问题        假设仓库中只能存放一件产品,生产者将生产出来的...
  • 生产者消费者问题 个生产者和个生产者的问题。生产者不断的向仓库放入产品,消费者不断的从仓库取出产品,仓库的容量是有限的。因此,当仓库处于满状态时,生产者必须等待消费者取出 1 个或个产品后才能继续...
  • 今天看了一片博文,讲Java线程之线程的协作,其中作者用程序实例说明了生产者消费者问题,但我及其他读者发现程序跑几次还是会出现死锁,百度搜了下大都数的例子也都存在bug,经过仔细研究发现其中的问题,并...
  • 生产者消费者问题详解

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

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

    千次阅读 多人点赞 2020-03-17 21:29:53
    1,生产者消费者问题 问题的提出 初步思考 进程资源共享关系和同步关系分析 问题的具体解决 第一搏 存在的问题 第二搏 维度思考 1,单生产者、单消费者、缓冲区 2,生产者、消费者、单缓冲 3,单...
  • 信号量与生产者消费者问题

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

    千次阅读 2018-03-28 19:04:43
    问题基本描述生产者消费者问题是一个著名的进程同步的问题。它描述的是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个...
  • 文章目录生产者消费者问题描述PV操作题目分析步骤多生产者多消费者问题描述问题分析吸烟者问题描述问题分析 生产者消费者问题描述 系统中有一组生产者进程和一组消费者进程,生产者进程每次生成一个产品放入...
  • 经典面试题,生产者消费者问题
  • 生产者消费者问题源程序

    千次阅读 2015-11-01 04:18:18
    生产者消费者问题(Producer-consumer problem)是一个线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是...
  • 本文使用C++描述,采用信号量与线程——解决了生产者消费者之间的同步与互斥操作。
  • 生产者消费者问题 C++实现

    万次阅读 多人点赞 2018-06-29 17:00:03
    生产者消费者问题 C++实现 知识准备 thread 介绍 成员类 成员函数 sleep_for 介绍 mutex 介绍 成员函数 unique_lock 介绍 成员函数 codition_variable 介绍 成员函数 代码示例 生产者消费者问题 ...
  • 生产者消费者问题线程中非常经典的线程同步问题,这些线程必须按照一定的生产率和消费率来访问共享缓冲区。实现方法是:设置两个信号量full和empty,其中full表示消费缓冲区的个数,empty表示生产缓冲区的个数...
  • 多个消费者多生产者

    千次阅读 2018-10-26 17:47:58
    之前的是单生产消费者 使用一个mutex解决生产者消费者问题 其中第2个例子使用了事件对象, 用于单线程的情况. 若在linux 上用信号量每次解锁一次即可; 如果要修改成个的情况,就要使用信号量.   先解决个...
  • 【操作系统】生产者消费者问题

    万次阅读 多人点赞 2018-08-11 00:43:20
    生产者消费者模型 生产者消费者模型 一、 生产者消费者问题 ... 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个线程同步问题的经典案...
  • java线程同步:生产者消费者问题

    千次阅读 多人点赞 2013-10-24 16:54:18
    消费者生产者问题是线程同步里边一个很经典的问题。 用通俗的语言来描述:一群生产者不断的生产产品,并将产品放到一个容器里边;同时一群消费者不断从容器里边消费产品。 容器的容量是有限的。如果容器满了,生产...
  • C语言线程之生产者消费者问题

    千次阅读 2018-06-17 20:44:58
    //设计可唤醒消费者生产者 void producer() { while (1) { //模拟正在生产 int d = 1 + rand () % 100;//代表生产的产品名字 delay(50000); //生产后产品入库 sem_wait(&unoccupied);//P操作,将对应的...
  • 1.生产者消费者问题 1.1.问题分析 1.2.如何实现 2.多生产者多消费者问题 2.1.问题描述 2.2.问题分析 2.3.如何实现 1.生产者消费者问题 1.1.问题分析 1.2.如何实现 2.多生产者多消费者问题 多是...
  • 第一种:1生产者1消费者1缓冲区 第二种:1生产者 2消费者 4缓冲区 ========================下面为修改作者源码得到的 3个生产者1个消费者4个缓冲区的情况==================  //1生产者 2消费者 4缓冲...
  • 生产/消费者问题是个非常典型的线程问题,涉及到的对象包括“生产者”、“消费者”、“仓库”和“产品”。他们之间的关系如下: (01) 生产者仅仅在仓储未满时候生产,仓满则停止生产。 (02) 消费者仅仅在仓储有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 307,812
精华内容 123,124
关键字:

多生产者多消费者问题