【问题标题】:Showing the unlock from std::condition_variable::wait显示来自 std::condition_variable::wait 的解锁
【发布时间】:2022-10-08 04:17:48
【问题描述】:

我从https://en.cppreference.com/w/cpp/thread/condition_variable/wait 读到wait() “原子地解锁锁”。我如何通过std::cout 看到这个?我试图更好地理解条件变量的实际作用。我在下面写了一个尝试。

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

using namespace std;

condition_variable cv;
mutex m;
bool stopped = false;

void f1() {
    unique_lock<mutex> ul{m};
    cout << "f1: " << ul.owns_lock() << endl;
    cv.wait(ul, [&]{
        cout << "f1: " << ul.owns_lock() << endl;
        return stopped;
    });
    cout << "f1 RUNNING\n";
    cout << "f1: " << ul.owns_lock() << endl;
}


void f2() {
    lock_guard<mutex> lg{m};
    cout << "f2 RUNNING\n";
}

int main() {
    unique_lock<mutex> ul{m};
    thread t1(&f1);
    thread t2(&f2);

    cout << ul.owns_lock() << endl;
    this_thread::sleep_for(chrono::seconds(1));
    stopped = true;
    cv.notify_one();
    cout << ul.owns_lock() << endl;
    ul.unlock();
    cout << ul.owns_lock() << endl;
    this_thread::sleep_for(chrono::seconds(1));

    t1.join();
    t2.join();
    return 0;
}

【问题讨论】:

  • 您永远不会看到 owns_lock() 返回 false,因为在 wait() 解锁互斥锁后线程立即进入睡眠状态。您可以 notify() 线程,然后它将执行谓词函数以确定是否继续等待,但在此检查期间将重新获取互斥锁,并且 owns_lock() 将返回 true。

标签: c++ c++11 std conditional-variable


【解决方案1】:

std::unique_lockstd::lock_guard 可用于满足 BasicLockable 要求的任何类类型。因此,只需编写您自己的包含std::mutex 的类,然后您就可以添加您想要的任何日志记录。例如:

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

using namespace std;

struct LoggingMutex
{
    mutex m;

    void lock() {
        cout << "Locking" << endl;
        m.lock();
        cout << "Locked" << endl;
    }

    bool try_lock() {
        cout << "Attempting to lock" << endl;
        bool result = m.try_lock();
        cout << (result ? "Locked" : "Not locked") << endl;
        return result;
    }

    void unlock() {
        cout << "Unlocking" << endl;
        m.unlock()
        cout << "Unlocked" << endl;
    }
};

condition_variable cv;
LoggingMutex lm;
bool stopped = false;

void f1() {
    unique_lock<LoggingMutex> ul{lm};
    cout << "f1: " << ul.owns_lock() << endl;
    cv.wait(ul, [&]{
        cout << "f1: " << ul.owns_lock() << endl;
        return stopped;
    });
    cout << "f1 RUNNING
";
    cout << "f1: " << ul.owns_lock() << endl;
}


void f2() {
    lock_guard<LoggingMutex> lg{lm};
    cout << "f2 RUNNING
";
}

int main() {
    unique_lock<LoggingMutex> ul{lm};
    thread t1(&f1);
    thread t2(&f2);

    cout << ul.owns_lock() << endl;
    this_thread::sleep_for(chrono::seconds(1));
    stopped = true;
    cv.notify_one();
    cout << ul.owns_lock() << endl;
    ul.unlock();
    cout << ul.owns_lock() << endl;
    this_thread::sleep_for(chrono::seconds(1));

    t1.join();
    t2.join();
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多