1. 程式人生 > >Boost, C++11,生產者消費者以及Qt生產者消費者例子

Boost, C++11,生產者消費者以及Qt生產者消費者例子

  • 先看個Qt的生產者消費者
#include <QtCore>
#include <iostream>

const int DataSize = 100000;
const int BufferSize = 4096;
char buffer[BufferSize];

QWaitCondition bufferIsNotFull;
QWaitCondition bufferIsNotEmpty;
QMutex mutex;
int usedSpace = 0;

class Producer : public QThread
{
public:
    void run();
};

void
Producer::run() { for (int i = 0; i < DataSize; ++i) { mutex.lock(); while (usedSpace == BufferSize) bufferIsNotFull.wait(&mutex); buffer[i % BufferSize] = "ACGT"[uint(std::rand()) % 4]; ++usedSpace; bufferIsNotEmpty.wakeAll(); mutex.unlock(); } } class
Consumer : public QThread { public: void run(); }; void Consumer::run() { for (int i = 0; i < DataSize; ++i) { mutex.lock(); while (usedSpace == 0) bufferIsNotEmpty.wait(&mutex); std::cerr << buffer[i % BufferSize]; --usedSpace; bufferIsNotFull.wakeAll(); mutex.unlock(); } std
::cerr << std::endl; } int main() { Producer producer; Consumer consumer; producer.start(); consumer.start(); producer.wait(); consumer.wait(); return 0; }
  • 在看一個Boost版本的生產者消費者

template<typename Data>  
class concurrent_queue  
{  
private:  
    std::queue<Data> the_queue;  
    mutable boost::mutex the_mutex;  
    boost::condition_variable the_condition_variable;  
public:  
    void push(Data const& data)  
    {  
        boost::mutex::scoped_lock lock(the_mutex);  
        the_queue.push(data);  
        lock.unlock();  
        the_condition_variable.notify_one();  
    }  
    bool empty() const 
    {  
        boost::mutex::scoped_lock lock(the_mutex);  
        return the_queue.empty();  
    }  
    bool try_pop(Data& popped_value)  
    {  
        boost::mutex::scoped_lock lock(the_mutex);  
        if(the_queue.empty())  
        {  
            return false;  
        }  

        popped_value=the_queue.front();  
        the_queue.pop();  
        return true;  
    }  
    void wait_and_pop(Data& popped_value)  
    {  
        boost::mutex::scoped_lock lock(the_mutex);  
        while(the_queue.empty())  
        {  
            the_condition_variable.wait(lock);  
        }  

        popped_value=the_queue.front();  
        the_queue.pop();  
    }  
};
  • 下面是c++11寫的
#include <mutex>
#include <condition_variable>
#include <deque>
#include <iostream>
using namespace std;
std::condition_variable QueueNotFull;
std::condition_variable QueueNotEmpty;
std::mutex  QueueMutex;
std::deque<int> Que;
const int MaxSize = 16
// 判斷佇列是否為空
bool Empty(){
    return Que.empty();
}
// 判斷佇列是否已滿
bool Full(){
    return Que.size() == MaxSize;
}
// 往佇列中新增資料
void Put(int element){
    std::unique_lock<std::mutex> locker(QueueMutex);
    while (Full()){
        cout << "Full !! Wait !!" << endl;
        QueueNotFull.wait(locker);
    }
    Que.push_back(element);
    // 通知其他執行緒,佇列不空
    QueueNotEmpty.notify_all();
}

// 從佇列中取出資料
int Get(){
    std::unique_lock<std::mutex> locker(QueueMutex);
    while (Empty()){
        cout << "Empty!! Wait!!" << endl;
        QueueNotEmpty.wait(locker);
    }
    int t = Que.front();
    Que.pop_front();
    // 通知其他等待的物件,佇列不滿
    QueueNotFull.notify_all();
    return t;
}

// 消費者執行緒
void GetFunc(){
    while (1){
        int var;
        var = Get();
        cout << "Get : " << var << endl;
    }
}

// 生產者執行緒
void PutFunc(){
    srand((unsigned int)time(0));
    while (1){
        int var = rand()%100;
        Put(var);
    }
}

int main(int arc,char** argv)
{
    // 啟動兩個執行緒
    std::thread td1(GetFunc);
    std::thread td2(PutFunc);
    td1.join();
    td2.join();
    return 0;
}
  • 下面是自己寫的一個c++11版本的
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <deque>
#include <thread>
std::condition_variable notFull;
std::condition_variable notEmpty;
std::mutex mtx;
std::deque<int> deq;
const int MAX_SIZE = 16;
bool empty(){
    return deq.empty();
}

bool full(){
    return deq.size() == MAX_SIZE;
}

void put(int num){
    std::unique_lock<std::mutex> lock(mtx);
    while (full()){
        notFull.wait(lock);
    }
    deq.push_back(num);
    notEmpty.notify_all();
}

int get(){
    std::unique_lock<std::mutex> lock(mtx);
    while (empty()){
        notEmpty.wait(lock);
    }
    int num = deq.front();
    deq.pop_front();
    notFull.notify_all();
    return num;
}


void putFunc(){
    int i = 0;
    while (i < 100000){
        put(i++);
    }
}

void getFunc(){
    int i = 0;
    while (i++ < 100){
        cout << get() << endl;
    }
}

int main()
{
    std::thread t1(putFunc);
    std::thread t2(getFunc);
    t1.join();
    t2.join();
    system("pause");
}

相關推薦

Boost, C++11,生產者消費者以及Qt生產者消費者例子

先看個Qt的生產者消費者 #include <QtCore> #include <iostream> const int DataSize = 100000; con

綜合運用: C++11 多線程下生產者消費者模型詳解(轉)

並發 rep 生產 我會 交流 模型 操作 const ref 生產者消費者問題是多線程並發中一個非常經典的問題,相信學過操作系統課程的同學都清楚這個問題的根源。本文將就四種情況分析並介紹生產者和消費者問題,它們分別是:單生產者-單消費者模型,單生產者-多消費者模型,多生產

C++11 併發指南九(綜合運用: C++11 多執行緒下生產者消費者模型詳解)

前面八章介紹了 C++11 併發程式設計的基礎(抱歉哈,第五章-第八章還在草稿中),本文將綜合運用 C++11 中的新的基礎設施(主要是多執行緒、鎖、條件變數)來闡述一個經典問題——生產者消費者模型,並給出完整的解決方案。 生產者消費者問題是多執行緒併發中一個非常經典的問題,相信學過作業系統課程的同學都清楚

用BlockBoundQueue和c++11實現多執行緒生產者消費者問題

最近在讀到陳碩的《linux多執行緒服務端程式設計》這書時,發現了兩個特別好用的模板類 : BlockQueue和BlockBoundQueue,用來實現多執行緒中的生產者消費者問題是特別方便的。但是其原始碼中用到boost庫,所以在這裡我稍微修改下,實現如下。

C++11 多執行緒下生產者消費者模型詳解

 前面八章介紹了 C++11 併發程式設計的基礎(抱歉哈,第五章-第八章還在草稿中),本文將綜合運用 C++11 中的新的基礎設施(主要是多執行緒、鎖、條件變數)來闡述一個經典問題——生產者消費者模型,並給出完整的解決方案。 生產者消費者問題是多執行緒併發中一個非常

c++11記憶體模型以及引用計數無鎖棧的實現

c++11提供了6中記憶體模型: memory_order_seq_cst(原子操作預設模型) memory_order_relaxed (沒有順序性的要求 memory_order_release memory_order_acquire memory_order

STL/Boost C++ 11 中foreach的用法

本篇將對C++ 標準庫中的兩種foreach,以及boost中的BOOST_FOREACH進行講解說明 #include <iostream> #include <algorithm> #include <string> #include

C++11實現生產者消費者

#include <iostream> #include <thread> #include <mutex> #include <deque> #include <vector> #include <condition

c++11多執行緒 生產者-消費者模型/條件變數condition_variable

1.生產者消費者模型: 在工作中,大家可能會碰到這樣一種情況:某個模組負責產生資料,這些資料由另一個模組來負責處理(此處的模組是廣義的,可以是類、函式、執行緒、程序等)。產生資料的 模組,就形象地稱為生產者;而處理資料的模組,就稱為消費者。在生產者與消費者之間在加個緩衝區

C++11實現生產者消費者模式

併發程式設計中,資料產生和資料處理在不同的執行緒,這些執行緒傳遞資料常用的就是生產者消費者模式 以下是模仿Java的BlockingQueue實現的生產者消費者模式: #pragma once

使用c++11,實現一個生產者-消費者模型

#include "stdafx.h" #include "Test.h" #include <process.h> #include <utility> #include <memory> #include <string>

c++11多執行緒中的condition_variable(生產者消費者示例)

#include <iostream> #include <string> #include <th

C#多線程學習(三) 生產者消費者

... new col 線程 簡單的 ons finally 訪問 read 前面說過,每個線程都有自己的資源,但是代碼區是共享的,即每個線程都可以執行相同的函數。這可能帶來的問題就是幾個線程同時執行一個函數,導致數據的混亂,產生不可預料的結果,因此我們必須避免這種情況的發

kafka模擬生產者-消費者以及自定義分割槽

基本概念 kafka中的重要角色   broker:一臺kafka伺服器就是一個broker,一個叢集可有多個broker,一個broker可以容納多個topic   topic:可以理解為一個訊息佇列的名字   partition:分割槽,為了實現擴充套件性,一個topic可以分佈到多

linux c語言實現佇列及用於生產者消費者模型

c語言沒有佇列的資料結構,需要自己實現//myqueue.h #ifndef __MYQUEUE_H__ #define __MYQUEUE_H__ #include <stdio.h> #include <stdlib.h> #define T

Linux C/C++多執行緒學習:生產者消費者問題

#include <iostream> #include <mutex> #include <condition_variable> #include <unistd.h> #include <thread> using namespace std;

多個消費者多個生產者

之前的是單生產消費者 使用一個mutex解決生產者消費者問題 其中第2個例子使用了事件物件, 用於單執行緒的情況. 若在linux 上用訊號量每次解鎖一次即可; 如果要修改成多個的情況,就要使用訊號量.   先解決多個生產 1個消費的問題: const i

通過c++11的std::bind及std::function實現類方法的回撥,模擬Qt實現訊號槽

c++11引入了std::bind及std::function,實現了函式的儲存和繫結,即先將可呼叫的物件儲存起來,在需要的時候再呼叫。網上有很多介紹。 Qt訊號槽實現訊號的傳送和接收,類似觀察者。簡單說明: sender:發出訊號的物件 signal:傳送物件

C++11 Boost Any類實現

#include "pch.h" #include <iostream> #include <memory> #include <typeindex> using namespace std; /* 類似於boost Any類的實現 */ struct A

(轉)用C++11的std::async代替執行緒的建立, 以及std::future,std::promise和std::packaged_task的使用

c++11中增加了執行緒,使得我們可以非常方便的建立執行緒,它的基本用法是這樣的: void f(int n); std::thread t(f, n + 1); t.join(); 但是執行緒畢竟是屬於比較低層次的東西,有時候使用有些不便,比如我希望獲取執