Mutex 没有像我预期的那样工作。我的错误是什么?

Mutex does not work as I expect. What is my mistake?

我试图找出数据竞赛的主题,并编写了这段代码。这里我们使用共享元素 wnd。我认为通过在 while 循环中放置锁,我会禁止 th1 线程与 wnd 一起工作,但这并没有发生,我看到 th1 线程的输出畅通无阻。

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

int main()
{
     bool wnd = true;
     std::mutex mutex;
     std::unique_lock<std::mutex> lock(mutex, std::defer_lock);


     std::thread th1([&]() {
         int i = 0;
         while (true)
         {
             ++i;
             if (wnd)
                 std::cout << i << "   WND TRUE" << std::endl;
             else
                 std::cout << i << "   WND FALSE" << std::endl;
             std::this_thread::sleep_for(std::chrono::milliseconds(100));
         }
     });

     
     while (true)
     {
        lock.lock();
         std::this_thread::sleep_for(std::chrono::milliseconds(2000));
         if (wnd)
             wnd = false;
         else
             wnd = true;
        lock.unlock();

         std::this_thread::sleep_for(std::chrono::milliseconds(100));
     }
     
     th1.join();
     return 0;
}

说实话,我希望看到 th1 线程在主线程在锁定部分内时停止打印 2+ 秒。

您没有正确使用互斥锁,特别是 std::unique_lock

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

int main()
{
     bool wnd = true;
     std::mutex mutex;

     std::thread th1{[&]() {
         for (int i = 0; i<10000; ++i)
         {   std::unique_lock<std::mutex> lock(mutex);
             std::cout << i << "\tWND\t " << std::boolalpha << wnd << std::endl;
         };
     }};

     for (int i = 0; i<30; ++i)
     {   std::unique_lock<std::mutex> lock(mutex);
         std::this_thread::sleep_for(std::chrono::milliseconds(2000));
         wnd = !wnd;
     }; 

     th1.join();
}

std::unique_lock uses its constructor operand as a resource whose acquisition is lock and release is unlock. It is designed to use RAII 作为保证互斥量正确 lock/unlock 序列的一种方式。延迟锁定仅意味着互斥锁在 std::unique_lock 的生命周期开始时未被锁定,这不是通常的用例。您可以手动 lock/unlock 互斥体,但这通常会导致可维护性降低,代码量增加 error-prone。 请记住,如果所涉及的线程没有争夺互斥体的所有权,则两者都不会等待对方;在您的原始程序中,工作线程没有接触互斥锁。但是在上面的程序中,两个线程都在竞争锁定互斥量;获胜者有机会继续他想做的事,而失败者必须等到互斥体解锁 - 这样他才能获得它的所有权。