std :: call_once锁免费吗? [英] Is std::call_once lock free?

查看:75
本文介绍了std :: call_once锁免费吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找出std :: call_once是否锁定. 是使用互斥量的call_once实现.但是为什么要使用互斥锁呢?我试图使用atomic_bool和CAS操作编写简单的实现.代码线程安全吗?

I want to find out if the std::call_once lock free. There are call_once implementations using mutex. But why should we use mutex? I tried to write simple implementation using atomic_bool and CAS operation. Is the code thread safe?

#include <iostream>
#include <thread>
#include <atomic>
#include <unistd.h>

using namespace std;
using my_once_flag = atomic<bool>;

void my_call_once(my_once_flag& flag, std::function<void()> foo) {
    bool expected = false;
    bool res = flag.compare_exchange_strong(expected, true,
                                            std::memory_order_release, std::memory_order_relaxed);
    if(res)
        foo();
}
my_once_flag flag;
void printOnce() {
    usleep(100);
    my_call_once(flag, [](){
       cout << "test" << endl;
    });
}

int main() {
    for(int i = 0; i< 500; ++i){
            thread([](){
                printOnce();
            }).detach();
    }
    return 0;
} 

推荐答案

您提出的实现不是线程安全的.它的确保证了foo()将仅通过此代码被调用一次,但是并不能保证所有线程都将从对foo()的调用中看到副作用.假设线程1执行比较并得到true,然后调度程序切换到线程2,然后线程2调用foo().线程2将变为false,跳过对foo()的调用,然后继续.由于尚未执行对foo()的调用,因此线程2可以在发生foo()的任何副作用之前继续执行.

Your proposed implementation is not thread safe. It does guarantee that foo() will only be called once through this code, but it does not guarantee that all threads will see side effects from the call to foo(). Suppose that thread 1 executes the compare and gets true, then the scheduler switches to thread 2, before thread 2 calls foo(). Thread 2 will get false, skip the call to foo(), and move on. Since the call to foo() has not been executed, thread 2 can continue executing before any side effects from foo() have occurred.

这篇关于std :: call_once锁免费吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆