c++ - 在单独的线程 C++ 上解锁时,互斥量不会解除阻塞

标签 c++ multithreading mutex

我试图理解为什么我的互斥锁的行为与我预期的不一样。

我正在调试另一个问题,并决定制作一个非常简单的可执行文件来直接测试互斥行为。这是我想出的:

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

int main(int argc, char** argv)
{
        std::mutex myMutex;

        auto threadGenerator = [&] (std::string printout)
        {
                auto threadFunctor = [&, printout] {

                        int count = 0;
                        while (count < 300)
                        {
                                std::lock_guard<std::mutex> lock(myMutex);


                                std::cout << printout << std::endl;
                                count++;

                                // Sleep ensures that the other thread will be waiting on mutex
                                // when I release lock
                                std::this_thread::sleep_for(std::chrono::milliseconds(10));
                        }
                };

                return threadFunctor;
        };

        auto thread1Functor = threadGenerator("Thread 1 got lock");
        auto thread2Functor = threadGenerator("Thread 2 got lock");

        std::thread thread1(thread1Functor);
        std::thread thread2(thread2Functor);

        thread1.join();
        thread2.join();

        return 0;
}

这只会产生两个重复锁定和解锁互斥锁的线程,同时打印一些输出。我添加了 sleep 以强制 lock_guard 阻塞并让线程相互等待。

这会产生以下输出:

Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock
Thread 1 got lock

最终,一旦线程 1 完成,线程 2 将再次开始获取锁。

他们不应该在线程 1 和线程 2 之间交替吗?锁应该在每次循环迭代结束时释放,这应该允许另一个线程控制互斥锁。为什么没有发生这种情况?有什么办法可以实现吗?

最佳答案

Shouldn't they be alternating between Thread 1 and Thread 2?

没有这样的保证。

The lock should be released at the end of each loop iteration, which should allow the other thread to take control of the mutex. Why isn't that happening?

因为您的第一个线程锁定互斥量,休眠,解锁互斥量然后再次尝试锁定互斥量。现在线程 1 和线程 2 都在尝试获取互斥锁,但是线程 1 处于运行状态,而线程 2 处于休眠状态,因此线程 1 最先获取互斥锁的可能性更大。

Is there any way to make it happen?

您的程序不应该区分线程,也不应该依赖于顺序。在实际情况下,多个线程等待互斥锁获取数据,一个线程将其放在那里,因此所有等待线程都处于等待状态,因此它们获得互斥锁的概率相似。但这可能特定于特定的硬件、操作系统和版本。您的程序不应依赖于哪个特定线程获取了互斥量。

关于c++ - 在单独的线程 C++ 上解锁时,互斥量不会解除阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42656410/

相关文章:

c++ - unordered_multimap::equal_range 慢

multithreading - 静态类的析构函数需要互斥锁吗?

c++ - "pthread_mutex_t mutex = {0}"是否初始化互斥量?

c++ - pthread广播然后等待?

c++ - 是否可以检查抽象类是否可复制构造,而忽略抽象?

c++ - 如何删除第一个数组的某个索引处的所有元素并且该索引取自第二个数组?

c++ 生成静态库,然后将其与 Clion/Cmake 一起使用

java - 调度程序在单元测试中工作不正确

multithreading - 使用 "Parallel.For"时并非所有项目都在绘制

c++ - 标准容器作为多线程应用程序中的局部变量