std::线程之间的互斥体同步

std::mutex syncronization between threads

本文关键字:同步 线程 之间 std      更新时间:2023-10-16

我有这个示例代码:

//#include "stdafx.h"    
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>

int g_num = 0;  // protected by g_num_mutex
std::mutex g_num_mutex;
void slow_increment(int id)
{
    std::cout << id << " STARTEDn";
    for (int i = 0; i < 100; ++i) {
        g_num_mutex.lock(); //STARTLOOP
        ++g_num;
        std::cout << id << " => " << g_num << 'n';
        std::this_thread::sleep_for(std::chrono::seconds(1));
        g_num_mutex.unlock();//ENDLOOP
       // std::this_thread::sleep_for(std::chrono::milliseconds(1));//UNCOMMENT THIS LINE TO GET A CORRECT WORKING
    }
}
int main()
{
    std::thread t1(slow_increment, 0);
    std::this_thread::sleep_for(std::chrono::seconds(6));
    std::thread t2(slow_increment, 1);
    t1.join();
    t2.join();
    return 0;
}

输出:

 0 STARTED
 0 => 1
 0 => 2
 0 => 3
 0 => 4
 0 => 5
 0 => 6
 1 STARTED // mutex.lock() is done?
 0 => 7
 0 => 8
 0 => 9
 0 => 10
 1 => 11 //aleatory number

如果我取消评论 1ms 睡眠,我会得到预期的工作:

0 STARTED
0 => 1
0 => 2
0 => 3
0 => 4
0 => 5
0 => 6
1 STARTED
1 => 7
0 => 8
1 => 9
0 => 10
1 => 11

我不明白线程 0 如何lock()unlock()互斥锁,当线程 1 在mutex.lock()中被阻塞时......

使用std::this_thread::yield()我看不到任何区别(在win32中(但std::this_thread::sleep_for(std::chrono::milliseconds(1))似乎有效...

随着 C++14/17 std::shared_timed_mutexstd::shared_mutex,以及lock_shared()/unlock_shared()我得到预期的结果......

有什么建议/解释吗?

您在睡眠时按住互斥锁;互斥锁一次解锁纳秒。如果系统在这几纳秒内没有检查线程 2(为什么会这样?(,那么你就会得到观察到的结果。

C++互斥锁是不公平的。如果您尝试锁定它,您不会仅仅因为您是最后一个锁定它的线程而被拒绝。