您的位置:首页 > 编程语言 > C语言/C++

《C++并发编程实战》读书笔记(1)

2016-07-21 11:59 357 查看
这两天开始看《C++并发编程实战》一书,感觉受益匪浅啊!

按照书中的同步并发操作(第四章)的内容,尝试编写线程安全的队列,模拟固定采集时间和不确定处理时间下的队列行为,供大家参考。

用到的C++多线程相关的主要内容为:mutex类(锁对象),lock_guard模板(实现锁对象的RAII用法),unique_lock模版,condition_variable类(用于进程间等待与唤醒)

另外,书中提供了非常好的技巧,如mutex对象在类中设置为mutable(可变),以用于静态成员函数等。

上代码,线程安全队列部分参考书上写的,仅供大家学习交流。

这个是threadsafe_queue的头文件:

#ifndef SQUEUE

#define SQUEUE

#include <queue>

#include <mutex>

#include <condition_variable>

#include <memory>

template<typename T>

class threadsafe_queue{

private:

    mutable std::mutex mut;

    std::queue<T> data_queue;

    std::condition_variable data_cond;

public:

    threadsafe_queue() = default;

    threadsafe_queue(const threadsafe_queue &other){

        std::lock_guard<std::mutex> lk(other.mut);

        data_queue = other.data_queue;

    }

    threadsafe_queue &operator=(const threadsafe_queue &other){

        std::lock_guard<std::mutex> lk(other.mut);

        data_queue = other.data_queue;

    }

    void push(T new_val){

        std::lock_guard<std::mutex> lk(mut);

        data_queue.push(new_val);

        data_cond.notify_all();

    }

    void wait_and_pop(T &value){

        std::unique_lock<std::mutex> lk(mut);

        data_cond.wait(lk, [this](){return !data_queue.empty(); });

        value = data_queue.front();

        data_queue.pop();

    }

    std::shared_ptr<T> wait_and_pop(){

        std::unique_lock<std::mutex> lk(mut);

        data_cond.wait(lk, [this](){return !data_queue.empty()});

        std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));

        data_queue.pop();

        return ptr;

    }

    bool try_pop(T &value){

        std::lock_guard<std::mutex> lk(mut);

        if (data_queue.empty())

            return false;

        value = data_queue.front();

        data_queue.pop();

        return true;

    }

    std::shared_ptr<T> try_pop(){

        std::lock_guard<std::mutex> lk(mut);

        if (data_queue.empty())

            return std::shared_ptr<T>();

        std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));

        data_queue.pop();

        return ptr;

    }

    bool empty() const{

        std::lock_guard<std::mutex> lk(mut);

        return data_queue.empty();

    }

    int size() const{

        std::lock_guard<std::mutex> lk(mut);

        return data_queue.size();

    }

};

#endif

测试代码:

#include "S_queue.h"

#include <vector>

#include <iostream>

#include <thread>

#include <string>

#include <random>

#include <condition_variable>

using namespace std;

void fun1(int value, threadsafe_queue<int> &iq){

    uniform_int_distribution<int> u(-100, 100);

    default_random_engine e(time(0));

    for (int i = 0; i != value; --i){

        this_thread::sleep_for(chrono::milliseconds(100));

        iq.push(u(e));

    }

}

void fun2(int value, threadsafe_queue<int> &iq){

    uniform_int_distribution<int> u(90, 105);

    default_random_engine e(time(0));

    for (int i = 0; i != value; --i){

        this_thread::sleep_for(chrono::milliseconds(u(e)));

        int val;

        cout << "Size: " << iq.size() << " —— ";

        iq.wait_and_pop(val);

        cout << "Value: " << val << endl;

    }

}

int _tmain(int argc, _TCHAR* argv[])

{

    string line;

    threadsafe_queue<int> iq;

    int num;

    cin >> num;

    thread t1(fun1, num, ref(iq)), t2(fun2, num, ref(iq));

    t1.join();

    t2.detach();

    cin >> line;

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息