std :: atomic_flag和std :: lock_guard

时间:2021-01-22 17:57:06

Since std::lock_guard doesn't work with std::atomic_flag I've implemented my own version:

由于std :: lock_guard不能与std :: atomic_flag一起使用,我实现了自己的版本:

class atomic_guard {
public:
    inline atomic_guard(std::atomic_flag& lock) : lock(lock) {
        while (this->lock.test_and_set()) {
            /* spin */ 
        };
    };

    inline ~atomic_guard() {
        this->lock.clear();
    };

private:
    std::atomic_flag& lock;
};

This seems to work fine. The question is: is this a correct way to implement RAII for std::atomic_flag? Also is there a built-in guard for that? If not, why? The specialization std::lock_guard<std::atomic_flag> looks like something very natural.

这似乎工作正常。问题是:这是为std :: atomic_flag实现RAII的正确方法吗?还有一个内置的守卫吗?如果没有,为什么?专业化std :: lock_guard 看起来很自然。

1 个解决方案

#1


2  

Your use of atomic_guard as a standalone mutex lookalike is correct, if slightly unusual.

您将atomic_guard用作独立的互斥体看起来是正确的,如果有点不寻常的话。

Using std::atomic_flag directly with std::lock_guard is not possible because the std::lock_guard template manages a mutex while std::atomic_flag is a (low-level) atomic boolean type.

直接使用std :: atomic_flag与std :: lock_guard是不可能的,因为std :: lock_guard模板管理互斥锁,而std :: atomic_flag是(低级)原子布尔类型。

A mutex implementation that can be used with std::lock_guard has to provide member functions lock and unlock and can be implemented like this:

可以与std :: lock_guard一起使用的互斥锁实现必须提供成员函数锁定和解锁,并且可以像这样实现:

class my_mutex {
    std::atomic_flag flag{ATOMIC_FLAG_INIT};

public:
    void lock()
    {
        while (flag.test_and_set());
    }

    void unlock()
    {
        flag.clear();
    }
};

Note that this is a very basic and inefficient mutex implementation, but it is compatible with std::lock_guard:

请注意,这是一个非常基本且低效的互斥实现,但它与std :: lock_guard兼容:

my_mutex mtx;

std::lock_guard<my_mutex> lck{mtx};

#1


2  

Your use of atomic_guard as a standalone mutex lookalike is correct, if slightly unusual.

您将atomic_guard用作独立的互斥体看起来是正确的,如果有点不寻常的话。

Using std::atomic_flag directly with std::lock_guard is not possible because the std::lock_guard template manages a mutex while std::atomic_flag is a (low-level) atomic boolean type.

直接使用std :: atomic_flag与std :: lock_guard是不可能的,因为std :: lock_guard模板管理互斥锁,而std :: atomic_flag是(低级)原子布尔类型。

A mutex implementation that can be used with std::lock_guard has to provide member functions lock and unlock and can be implemented like this:

可以与std :: lock_guard一起使用的互斥锁实现必须提供成员函数锁定和解锁,并且可以像这样实现:

class my_mutex {
    std::atomic_flag flag{ATOMIC_FLAG_INIT};

public:
    void lock()
    {
        while (flag.test_and_set());
    }

    void unlock()
    {
        flag.clear();
    }
};

Note that this is a very basic and inefficient mutex implementation, but it is compatible with std::lock_guard:

请注意,这是一个非常基本且低效的互斥实现,但它与std :: lock_guard兼容:

my_mutex mtx;

std::lock_guard<my_mutex> lck{mtx};