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为空时,消费者就会阻塞,并且会通知生产者去生产;

原文地址:https://www.cnblogs.com/wanghao-boke/p/15421640.html