内容纲要

C++多线程信号量

一、std::condition_variable

https://en.cppreference.com/w/cpp/thread/condition_variable

  1. condition_variable可以等待mutex
  2. 使用wait/wait_for/wait_until等待mutex,并且可以传入函数,验证条件是否满足,如果不满足,则等待,直到条件满足,才继续执行
  3. 使用notify_one唤醒一个线程,notify_all唤醒所有
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
    // wait until main() sends data
    std::unique_lock lk(m);
    cv.wait(lk, []{ return ready; });

    // after the wait, we own the lock
    std::cout << "Worker thread is processing data\n";
    data += " after processing";

    // send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";

    // manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}

int main()
{
    std::thread worker(worker_thread);

    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard lk(m);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();

    // wait for the worker
    {
        std::unique_lock lk(m);
        cv.wait(lk, []{ return processed; });
    }
    std::cout << "Back in main(), data = " << data << '\n';

    worker.join();
}

二、std::unique_lock

https://en.cppreference.com/w/cpp/thread/unique_lock

  1. 声明时不加锁,可以使用std::lock或者std::condition_variable::wait加锁
  2. 析构时会自动解锁
  3. std::lock同时给多个一起上锁,用于避免死锁
void transfer(Box& from, Box& to, int num)
{
    // don't actually take the locks yet
    std::unique_lock lock1{from.m, std::defer_lock};
    std::unique_lock lock2{to.m, std::defer_lock};

    // lock both unique_locks without deadlock
    std::lock(lock1, lock2);

    from.num_things -= num;
    to.num_things += num;

    // “from.m” and “to.m” mutexes unlocked in unique_lock dtors
}
最后修改日期: 2024年5月20日

作者