zoukankan      html  css  js  c++  java
  • C++ 线程同步(二)

    [参考](07 C++ 线程间同步 - 知乎 (zhihu.com)

    消费者和生产者

    std::mutex

    std::thread

    1. 消费者“被动等待”

    #include<iostream>
    #include<thread>
    #include<deque>
    #include<mutex>
    // using namespace std;
    
    static std::mutex mtx;
    static std::deque<int> dq;
    static int productNum = 5;
    
    void Producer() {
        using namespace std::literals::chrono_literals;
        for (int i = 0; i < productNum; ++i) {
            mtx.lock();
            dq.push_front(i);
            std::cout << "producer i : " << i << std::endl;
            mtx.unlock(); 
        //std::this_thread::sleep_for(1s); } }
    void Consumer() { while (1) { if (dq.empty()) { continue; } mtx.lock(); int data = dq.back(); dq.pop_back(); std::cout << "Consumer : data = " << data << std::endl; mtx.unlock(); } } int main() { std::thread t1(Producer); std::thread t2(Consumer); t2.join(); t1.join(); return 0; }

    注:编译时记得加上 -lpthread

    运行结果:

    producer i : 0
    producer i : 1
    producer i : 2
    producer i : 3
    producer i : 4
    Consumer : data = 0
    Consumer : data = 1
    Consumer : data = 2
    Consumer : data = 3
    Consumer : data = 4
    ^C

    消费者端,使用的是 while(1) 循环,会一直等待 dq 里面的数据

    其中

    如果将生产者在生产完一个物品后休眠1s

    则输出结果为

    producer i : 0
    Consumer : data = 0
    producer i : 1
    Consumer : data = 1
    producer i : 2
    Consumer : data = 2
    producer i : 3
    Consumer : data = 3
    producer i : 4
    Consumer : data = 4
    ^C

    2、消费者主动出击:

    #include<iostream>
    #include<mutex>
    #include<vector>
    #include<thread>
    #include<condition_variable>
    
    std::mutex mtx;
    std::condition_variable cv;
    std::vector<int> vec;
    int produceNum = 5;
    
    void Producer() {
        for (int i = 0; i <= produceNum; ++i) {
            std::unique_lock<std::mutex> lock(mtx);
            while (!vec.empty()) {
                cv.wait(lock);
            }
    
            vec.push_back(i);
            std::cout << "Producer : " << i << std::endl;
            cv.notify_all();
        }
    }
    
    void Consumer() {
        while (1) {
            std::unique_lock<std::mutex> lock(mtx);
            while (vec.empty()) {
                cv.wait(lock);
            }
    
            int data = vec.back();
            vec.pop_back();
            std::cout << "Consumer : " << data << std::endl;
            cv.notify_all();
        }
    }
    
    int main() {
        std::thread t1(Producer);
        std::thread t2(Consumer);
        t1.join();
        t2.join();
        return 0;
    }

    执行结果如下:

    Producer : 0
    Consumer : 0
    Producer : 1
    Consumer : 1
    Producer : 2
    Consumer : 2
    Producer : 3
    Consumer : 3
    Producer : 4
    Consumer : 4
    Producer : 5
    Consumer : 5
    ^C

    注释:

    该实例中消费者和生产者对应两个线程,当vec中有数据时,生产者就会阻塞,并且通知消费者去消费;

    当vec为空时,消费者就会阻塞,并且会通知生产者去生产;

  • 相关阅读:
    位运算及其妙用
    Ubuntu 下的Python开发 mysqlclient安装失败问题解决,亲测有效
    Ubuntu "sudo apt update"失败的问题可以这样解决
    青魔法-驭虫术(不定时更新)
    白魔法安全课(持续更新)
    空间魔法-Mysql(持续更新)
    时间魔法-Git(持续更新)
    仪式魔法——区块链(持续更新)
    Web圣堂幻术VUE不定时更新)
    影魔法 Shell 与 Dos(持续更新)
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/15421640.html
Copyright © 2011-2022 走看看