Muduo::blockingqueue, Boundedblockingqueue analysis

Source: Internet
Author: User
Tags assert mutex

    • Blockingqueue
    • Boundedblockingqueue

Before learning the source code, first understand a concept: bounded buffering and unbounded buffering.

To the producer, the consumer model.
Bounded buffering refers to the producer when adding data to the warehouse to determine whether the warehouse is full, if it is full notify consumers to take away the data. Consumers in the consumption, first determine whether the warehouse is empty, if it is the first to inform producers of production data.

Blockingqueue

In the unbounded buffer, the producer does not care whether the warehouse is full, just add the data, and the consumer waits for the producer's signal when judging the warehouse is empty. Only one semaphore is required.

Blockingqueue is a model like this.

Template<TypeNameT>classblockingqueue:boost::noncopyable{ Public: Blockingqueue (): Mutex_ (),//Initialize mutex firstNotempty_ (Mutex_),//re-use the mutex to initialize the signal.Queue_ () {}voidPutConstt& x)//Production data{Mutexlockguard lock (mutex_);    Queue_.push_back (x); Notempty_.notify ();//Wait morphing saves us    //http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/}#ifdef __gxx_experimental_cxx0x__  voidPut (t&& x)//Right value{Mutexlockguard lock (mutex_); Queue_.push_back (STD:: Move (x));  Notempty_.notify (); }//Fixme:emplace ()#endifT Take ()//Consumption data{Mutexlockguard lock (mutex_);//Always use a while-loop, due to spurious wakeup     while(Queue_.empty ())//Warehouse is empty{notempty_.wait ();//Waiting for producer signals} assert (!queue_.empty ());#ifdef __gxx_experimental_cxx0x__T Front (STD:: Move (Queue_.front ()));#elseT Front (Queue_.front ());#endifQueue_.pop_front ();returnFront } size_t Size ()Const{Mutexlockguard lock (mutex_);returnQueue_.size (); }Private:mutableMutexlock mutex_;//Mutex amountCondition notempty_;//Signal Volume  STD:: deque<T>Queue_;//Warehouse};

Can write a producer consumer test code, with this blockingqueue, do not have their own in the management of mutual exclusion and signal volume.

#include <muduo/base/BlockingQueue.h>#include <muduo/base/Thread.h>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>#include <iostream>using namespaceMuduo;using namespaceBoostvoidProduce (shared_ptr<BlockingQueue<int> >Queue){ while(true)    {intProduct=rand ()% ++1;STD::cout<<"Produce:"<<product<<STD:: Endl;Queue->put (product); Sleep (rand ()%5); }}voidConsome (shared_ptr<BlockingQueue<int> >Queue){ while(true)    {intproduct=Queue->take ();STD::cout<<"Consome:"<<product<<STD:: Endl; }}intMain () {shared_ptr<BlockingQueue<int> > Blockingqueue (Newblockingqueue<int>);    Thread T1 (boost::bind (produce, blockingqueue));    Thread T2 (Boost::bind (Consome, blockingqueue));    T1.start ();    T2.start ();    T1.join (); T2.join ();return 0;}
Boundedblockingqueue

Unlike Blockingqueue, boundedblockingqueue have boundaries, i.e. warehouses are limited. At this time the warehouse has four states: non-empty, empty, not full, full.

When the producer produces, it will first determine whether the warehouse is full, if it is waiting for the warehouse is not full signal, otherwise add goods to the warehouse, then notify the consumer warehouse non-empty.

When the customer takes the goods to determine whether the warehouse is empty, if it is waiting for the warehouse non-empty signal, otherwise take away the goods, notify the producer warehouse is not full.

At this time to achieve the producer consumer model needs 2 signal volume, a non-null, indicating that consumers can consume; one is full, indicating that the producer can produce it. The source code is as follows:

Template<typename T>class boundedblockingqueue:boost::noncopyable{ Public:Explicit Boundedblockingqueue(intmaxSize)//maximum capacity:mutex_(),Notempty_(Mutex_),Notfull_(Mutex_),Queue_(maxSize) {  }voidPutConstt& x) {MutexlockguardLock(MUTEX_); while(Queue_.full ())//Warehouse is full{notfull_.wait ();//wait for a non-full signal, that is, consumers will be notified after consumption} assert (!queue_.full ());    Queue_.push_back (x); Notempty_.notify ();//Notify consumer that the warehouse is in stock (not empty)} T Take () {MutexlockguardLock(MUTEX_); while(Queue_.empty ())//Warehouse is empty{notempty_.wait ();//Waiting for producers to add goods to the warehouse} assert (!queue_.empty ());    T Front (Queue_.front ());    Queue_.pop_front (); Notfull_.notify ();//Inform the producer that the warehouse is no longer available    returnFront }BOOLEmpty ()Const{MutexlockguardLock(MUTEX_);returnQueue_.empty (); }BOOLFull ()Const{MutexlockguardLock(MUTEX_);returnQueue_.full (); } size_t Size ()Const{MutexlockguardLock(MUTEX_);returnQueue_.size (); } size_t Capacity ()Const{MutexlockguardLock(MUTEX_);returnQueue_.capacity (); }Private: mutable mutexlock mutex_; Condition notempty_;//Non-empty signal volumeCondition Notfull_;//non-full signal volumeBoost::circular_buffer<t> Queue_;};

Test code:

//boundedblokcingqueue.cpp#include <muduo/base/BoundedBlockingQueue.h>#include <muduo/base/Thread.h>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>#include <iostream>using namespaceMuduo;using namespaceBoostvoidProduce (shared_ptr<BoundedBlockingQueue<int> >Queue){ while(true)    {intProduct=rand ()% ++1;STD::cout<<"Produce:"<<product<<STD:: Endl;Queue->put (product); Sleep (rand ()%5); }}voidConsome (shared_ptr<BoundedBlockingQueue<int> >Queue){ while(true)    {intproduct=Queue->take ();STD::cout<<"Consome:"<<product<<STD:: Endl; Sleep (rand ()%5); }}intMain () {shared_ptr<BoundedBlockingQueue<int> > Boundedblockingqueue (Newboundedblockingqueue<int> (5));    Thread T1 (boost::bind (produce, boundedblockingqueue));    Thread T2 (Boost::bind (Consome, boundedblockingqueue));    T1.start ();    T2.start ();    T1.join (); T2.join ();return 0;}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Muduo::blockingqueue, Boundedblockingqueue analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.