C++ 初始化 std::atomic_bool ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15750917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:44:30  来源:igfitidea点击:

Initializing std::atomic_bool?

c++c++11visual-studio-2012atomic

提问by Sapd

I want to use std::atomic_boolbecause I want to have a boolean which is supposed to be accessed by different threads.

我想使用std::atomic_bool是因为我想要一个布尔值,它应该被不同的线程访问。

It's a staticmember Variable. The Problem is that I want to initialize it with falseas the first state. Normally I would do it like that: std::atomic_bool World::mStopEvent = false;

它是一个static成员变量。问题是我想将它初始化false为第一个状态。通常我会这样做: std::atomic_bool World::mStopEvent = false;

But the problems seems to be that it doesn't take falseas the constructor. So how I am supposed to initialize such a variable? I am using VS 2012.

但问题似乎是它不false作为构造函数。那么我应该如何初始化这样一个变量呢?我正在使用 VS 2012。

采纳答案by user7116

This is a known issue in Visual Studio 2012 (known as VC11), you should vote on the existing Connect item so that Microsoft knows it affects more folks as they've deferred the fix.

这是Visual Studio 2012(称为 VC11)中的一个已知问题,您应该对现有的 Connect 项目进行投票,以便 Microsoft 知道它会影响更多人,因为他们推迟了修复。

Hi,

Thanks for reporting this bug. I'm Microsoft's maintainer of the STL, and I wanted to let you know that while this bug remains active in our database, it won't be fixed in VC11 RTM (VS 2012 RTM). All bugs are important to us, but some are more severe than others and rise to the top of our priority queue.

I'm copying-and-pasting this response across all of the STL's active Connect bugs, but the following terse comments apply specifically to your bug:

  • Yep, we're missing these constructors on atomic_bool, atomic_int, etc. (atomic<bool>, atomic<int>, etc. have them). 29.5 [atomics.types.generic]/7 says "There shall be named types corresponding to the integral specializations of atomic, as specified in Table 145, and a named type atomic_boolcorresponding to the specified atomic<bool>. Each named type is a either typedefto the corresponding specialization or a base class of the corresponding specialization. If it is a base class, it shall support the same member functions as the corresponding specialization." which makes me really want to use typedefs (1 type is always simpler than 2 types), but I'll need to see if that would introduce any other issues.

I can't promise when we'll be able to resolve this bug, but we hope to do so as soon as possible (and I'll send another response when that happens) - our first opportunity will be the "out of band" release between VC11 and VC12 that Herb Sutter announced at the GoingNative 2012 conference.

Note: Connect doesn't notify me about comments. If you have any further questions, please E-mail me.

Stephan T. Lavavej Senior Developer - Visual C++ Libraries [email protected]

你好,

感谢您报告此错误。我是 Microsoft 的 STL 维护者,我想让您知道,虽然这个错误在我们的数据库中仍然存在,但它不会在 VC11 RTM (VS 2012 RTM) 中修复。所有错误对我们都很重要,但有些错误比其他错误更严重,并上升到我们优先队列的顶部。

我在所有 STL 的活动 Connect 错误中复制并粘贴此响应,但以下简洁的评论特别适用于您的错误:

  • 是的,我们缺少对这些构造atomic_boolatomic_int等等(atomic<bool>atomic<int>,等有他们)。29.5 [atomics.types.generic]/7 说“应该有与 atomic 的整数特化相对应的命名类型,如表 145 中指定的,以及atomic_bool与指定的 对应的命名类型atomic<bool>。每个命名类型都是typedef对应特化的一个或相应特化的基类。如果是基类,则应支持与相应特化相同的成员函数。” 这让我真的很想使用 typedef(1 种类型总是比 2 种类型简单),但我需要看看这是否会引入任何其他问题。

我不能保证我们什么时候能够解决这个错误,但我们希望尽快解决(如果发生这种情况,我会发送另一个回复)——我们的第一个机会将是“带外” Herb Sutter 在 GoingNative 2012 会议上宣布的 VC11 和 VC12 之间的版本。

注意:Connect 不会通知我有关评论的信息。如果您有任何进一步的问题,请给我发电子邮件。

Stephan T. Lavavej 高级开发人员 - Visual C++ 库 [email protected]

Basically, you'll need to use std::atomic<T>for now.

基本上,您std::atomic<T>现在需要使用。

回答by andrewrk

回答by Andy Prowl

PROBLEM:

问题:

You cannot use copy-initialization, because std::atomic_boolis not copy-constructible:

您不能使用copy-initialization,因为std::atomic_bool不可复制构造:

std::atomic_bool World::mStopEvent = false; // ERROR!

In fact, the above is equivalent to:

其实上面的等价于:

std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!

However, you can use direct-initialization:

但是,您可以使用直接初始化

std::atomic_bool World::mStopEvent(false);

At your wish, you may choose to use braces instead of parentheses:

根据您的意愿,您可以选择使用大括号而不是圆括号:

std::atomic_bool World::mStopEvent{false};

BUG:

漏洞:

While copy-initialization is illegal no matter what compiler you choose, it seems that the implementation of the Standard Library shipped with VC11 has a bug that won't let you perform direct-initialization either.

尽管无论您选择哪种编译器,复制初始化都是非法的,但似乎 VC11 附带的标准库的实现有一个错误,它也不允许您执行直接初始化。

So how I am supposed to initialize such a variable?

那么我应该如何初始化这样一个变量呢?

WORKAROUND:

解决方法:

As a possible workaround, you can provide a pair of static getter/setter wrappers that - respectively - set and return the value of the atomic boolean flag, but not before making sure it has been initialized at least once and not more than once to the desired initial value in a thread-safe manner (you can consider this some kind of lazy initialization):

作为一种可能的解决方法,您可以提供一对静态 getter/setter 包装器,分别设置和返回原子布尔标志的值,但在确保它已被初始化至少一次且不超过一次之前提供给以线程安全的方式所需的初始值(您可以将其视为某种延迟初始化):

#include <atomic>
#include <mutex>

struct World
{
    static bool is_stop_event_set()
    {
        std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; });
        return mStopEvent;
    }

    static void set_stop_event(bool value)
    {
        std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; });
        mStopEvent = value;
    }

    static std::atomic_bool mStopEvent;
    static std::once_flag mStopEventInitFlag;
};

std::atomic_bool World::mStopEvent;
std::once_flag World::mStopEventInitFlag;

Now instead of accessing mStopEventdirectly, its value shall be read through the is_stop_event_set()function:

现在不是mStopEvent直接访问,而是通过is_stop_event_set()函数读取它的值:

#include <iostream>

int main()
{
    std::cout << World::is_stop_event_set(); // Will return false
}

回答by Bill Lynch

How about:

怎么样:

std::atomic_bool World::mStopEvent(false);