菜鸟笔记
提升您的技术认知

c scoped-ag真人游戏

考虑互斥量的使用,最基本的代码是:

 1 #include 
 2 #include 
 3 #include   
 4 
 5 std::mutex g_my_mutex;
 6 
 7 std::lock_guard make_lock() {
 8     return std::lock_guard(g_my_mutex);
 9 }
10 
11 void workonresource1() {
12 
13     for (int i = 0; i < 10000;   i)
14     {
15         std::lock_guard lk(g_my_mutex);
16         --gi;
17     }
18 }
19 
20 void workonresource2() {
21 
22     for (int i = 0; i < 10000;   i)
23     {
24         auto lk = make_lock();
25           gi;
26     }
27 }
28 
29 int main() {
30 
31     std::thread t1(workonresource1);
32     std::thread t2(workonresource2);
33 
34     t1.join();
35     t2.join();
36     
37     std::cout << "gi=" <

这在很多例子里都常见。等等,为什么第8行编译不过去?那是因为您没有在c 17下编译。std::lock_guard是禁止拷贝和移动的。c 17 granteed copy ellision允许第8行编译通过。

比较一下,第24行和第15行,哪个更简洁一些呢?

std::lock_guard还可以这样用:

void workonresource1() {
    for (int i = 0; i < 10000;   i)
    {
        g_my_mutex.lock();
        std::lock_guard lk(g_my_mutex, std::adopt_lock);
        --gi;
    }
}

意思就是,当lk对象构造时,不去调用mutex::lock()。因为之前自己所持有的锁已经lock了一次了(g_my_mutex.lock())。adopt就是这个意思的表达,英文的含义是收养。

当lk析构时,对g_my_mutex调用mutex::unlock,这一点没有变化。

现在考虑unique_lock的用法:用于更复杂的互斥量操作上,例如:有超时时间的加锁。

#include 
#include 
#include           // std::mutex, std::lock_guard 
#include 
using ms = std::chrono::milliseconds;
using namespace std;
int gi = 0;
std::timed_mutex g_my_mutex;
std::lock_guard make_lock() {
    return std::lock_guard(g_my_mutex);  //绝不能分行写
}
void workonresource1() {
    for (int i = 0; i < 10000;   i)
    {
        auto lk = make_lock();
          gi;
    }
}
std::unique_lock make_lock2() {
    std::unique_lock lk(g_my_mutex, std::defer_lock);
    return lk;  //故意分行写
}
void workonresource2() {
    for (int i = 0; i < 10000;   i)
    {
        auto lk = make_lock2();
        while(lk.try_lock_for(ms(100))==false){
            std::cout << "lock fail. reason timeout. now retry...";
        }
        --gi;
    }
}
int main() {
    std::thread t1(workonresource1);
    std::thread t2(workonresource2);
    t1.join();
    t2.join();
    
    std::cout << "gi=" <

unique_lock支持move语义,这样它就能飞出{}之外了。像极了std::unique_ptr。同样的,它也是raii的,当析构时,调用mutex::unlock().

std::defer_lock是个全局变量,类型是std::defer_lock_t。显然,它用于函数的重载解析时,选不同的函数执行的。defer_lock的意思是,暂时不对g_my_mutex调用任何加锁动作。

为了证明,unique_lock是可以move的,可以这样:

std::unique_lock lk(g_my_mutex, std::defer_lock);
std::unique_lock lk2(std::move(lk));
lk2.lock();

scoped_lock是c 17新引进的,在处理多个互斥量时,特别简单:

参考:http://en.cppreference.com/w/cpp/thread/scoped_lock

网站地图