标签: atomic

标准的原子布尔和原子旗之间的区别

我不知道std::atomic变量,但是知道std::mutex标准提供的(奇怪的权利!); 然而有一件事引起了我的注意:标准提供了两种看似相同(对我而言)的原子类型,如下所示:

  1. std::atomic<bool> 类型

  2. std::atomic_flag 类型

它也以 - 的例子提到std::atomic_flag type-

std :: atomic_flag是一种原子布尔类型.与std :: atomic的所有特化不同,它保证是无锁的.与std :: atomic不同,std :: atomic_flag不提供加载或存储操作.

我不明白.std::atomic bool type不保证是无锁的吗?那它不是原子的还是什么?

那么两者之间有什么区别呢?我应该在何时使用哪种?

c++ multithreading atomic thread-safety c++11

45
推荐指数
2
解决办法
8254
查看次数

std :: atomic <std :: string>是否正常工作?

我正在阅读Anthony Williams的"行动中的C++并发"和第5章,其中讨论了新的多线程感知内存模型和原子操作,并指出:

为了std::atomic<UDT>用于某些用户定义的UDT类型,此类型必须具有普通的复制赋值运算符.

据我了解,这意味着std::atomic<UDT>如果以下内容返回true ,我们可以使用:

std::is_trivially_copyable<UDT>::value
Run Code Online (Sandbox Code Playgroud)

通过这种逻辑,我们不应该使用它std::string作为模板参数std::atomic并使其正常工作.

但是,以下代码使用预期输出进行编译和运行:

#include <atomic>
#include <thread>
#include <iostream>
#include <string>

int main()
{
    std::atomic<std::string> atomicString;

    atomicString.store( "TestString1" );

    std::cout << atomicString.load() << std::endl;

    atomicString.store( "TestString2" );

    std::cout << atomicString.load() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是一个未定义的行为,恰好按预期行事吗?

提前致谢!

c++ atomic stdstring stdatomic

44
推荐指数
2
解决办法
2万
查看次数

SQL原子增量和锁定策略 - 这样安全吗?

我有一个关于SQL和锁定策略的问题.例如,假设我的网站上有图像的视图计数器.如果我有一个或类似的,请执行以下语句:

START TRANSACTION;
UPDATE images SET counter=counter+1 WHERE image_id=some_parameter;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

假设特定image_id的计数器在时间t0具有值"0".如果两个会话更新相同的图像计数器,s1和s2,在t0同时启动,那么这两个会话是否都有可能读取值'0',将其增加为'1'并且都尝试将计数器更新为'1 ',那么计数器会得到值'1'而不是'2'?

s1: begin
s1: begin
s1: read counter for image_id=15, get 0, store in temp1
s2: read counter for image_id=15, get 0, store in temp2
s1: write counter for image_id=15 to (temp1+1), which is 1 
s2: write counter for image_id=15 to (temp2+1), which is also 1
s1: commit, ok
s2: commit, ok
Run Code Online (Sandbox Code Playgroud)

结果:image_id = 15的值'1'不正确,应为2.

我的问题是:

  1. 这种情况可能吗?
  2. 如果是这样,事务隔离级别是否重要?
  3. 是否有冲突解决方案将这种冲突视为错误?
  4. 可以使用任何特殊语法以避免出现问题(例如比较和交换(CAS)或显式锁定技术)吗?

我对一般答案很感兴趣,但如果没有,我对MySql和InnoDB特定的答案感兴趣,因为我正在尝试使用这种技术在InnoDB上实现序列.

编辑:以下方案也可能,导致相同的行为.我假设我们处于隔离级别READ_COMMITED或更高级别,因此s2从事务开始获取值,尽管s1已经向计数器写入"1".

s1: begin
s1: begin
s1: read counter …
Run Code Online (Sandbox Code Playgroud)

sql locking atomic increment

43
推荐指数
2
解决办法
1万
查看次数

Java:没有AtomicFloat或AtomicDouble吗?

我找到了AtomicInteger,AtomicLong但是AtomicFloat(或AtomicDouble)在哪里?也许有一些伎俩?

java concurrency atomic

43
推荐指数
3
解决办法
3万
查看次数

C++ 11中的Double-Checked Lock Singleton

以下单例实现数据 - 竞争是免费的吗?

static std::atomic<Tp *> m_instance;
...

static Tp &
instance()
{
    if (!m_instance.load(std::memory_order_relaxed))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!m_instance.load(std::memory_order_acquire))
        {
            Tp * i = new Tp;
            m_instance.store(i, std::memory_order_release);    
        }    
    }

    return * m_instance.load(std::memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)

std::memory_model_acquire了负载运行的多余?是否可以通过将它们切换到进一步放宽加载和存储操作std::memory_order_relaxed?在这种情况下,获取/释放语义是否std::mutex足以保证其正确性,或者std::atomic_thread_fence(std::memory_order_release)还需要确保构造函数的内存写入在轻松存储之前发生?然而,使用栅栏相当于有商店memory_order_release吗?

编辑:感谢John的回答,我提出了以下应该是数据竞争的实现.尽管内部负载可能完全是非原子的,但我决定放弃一个宽松的负载,因为它不会影响性能.与总是具有获取存储器顺序的外部负载相比,thread_local机器提高了访问大约一个数量级的实例的性能.

static Tp &
instance()
{
    static thread_local Tp *instance;

    if (!instance && 
        !(instance = m_instance.load(std::memory_order_acquire)))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!(instance = m_instance.load(std::memory_order_relaxed)))
        {
            instance = new Tp; 
            m_instance.store(instance, std::memory_order_release);    
        }    
    }
    return …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic c++11

43
推荐指数
3
解决办法
1万
查看次数

我必须明确调用原子加载/存储吗?

C++ 11引入了std::atomic<>模板库.该标准指定原子设置/获取由多个线程共享的变量的store()load()操作.

我的问题是分配和访问操作也是原子的吗?

即,是:

std::atomic<bool> stop(false);
...
void thread_1_run_until_stopped()
{
    if(!stop.load())
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop.store(true);
}
Run Code Online (Sandbox Code Playgroud)

相当于:

void thread_1_run_until_stopped()
{
    if(!stop)
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop = true;
}
Run Code Online (Sandbox Code Playgroud)

c++ atomic c++11

41
推荐指数
2
解决办法
2万
查看次数

如何自动否定std :: atomic_bool?

天真的布尔否定

std::atomic_bool b;
b = !b;
Run Code Online (Sandbox Code Playgroud)

似乎不是原子的.我怀疑这是因为operator!触发了一个简单的演员bool.如何以原子方式执行等效否定?以下代码说明了天真的否定不是原子的:

#include <thread>
#include <vector>
#include <atomic>
#include <iostream>

typedef std::atomic_bool Bool;

void flipAHundredThousandTimes(Bool& foo) {
  for (size_t i = 0; i < 100000; ++i) {
    foo = !foo;
  }
}

// Launch nThreads std::threads. Each thread calls flipAHundredThousandTimes 
// on the same boolean
void launchThreads(Bool& foo, size_t nThreads) {

  std::vector<std::thread> threads;
  for (size_t i = 0; i < nThreads; ++i) {
    threads.emplace_back(flipAHundredThousandTimes, std::ref(foo));
  }

  for (auto& thread : threads) …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic c++11

40
推荐指数
1
解决办法
8366
查看次数

在x86/x86_64处理器上使用LFENCE指令是否有意义?

通常在互联网上我发现LFENCE在处理器x86中没有任何意义,即它什么都不做,所以相反MFENCE我们可以绝对无痛地使用SFENCE,因为MFENCE= SFENCE+ LFENCE= SFENCE+ NOP= SFENCE.

但是如果LFENCE没有意义,那么为什么我们有四种方法在x86/x86_64中建立顺序一致性:

  1. LOAD(没有围栏)和STORE+MFENCE
  2. LOAD (没有围栏)和 LOCK XCHG
  3. MFENCE+ LOADSTORE(没有围栏)
  4. LOCK XADD(0)和STORE(没有围栏)

取自这里:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

以及Herb Sutter在第34页底部的表演:https://skydrive.live.com/view.aspx?status = 4E86B0CF20EF15AD!24884&app = WordPdf&wdo = 2&authkey =!AMtj_EflYn2507c

如果LFENCE没有做任何事情,那么方法(3)将具有以下含义:SFENCE + LOAD and STORE (without fence)但是SFENCE之前没有任何意义LOAD.即如果LFENCE什么都不做,方法(3)没有意义.

LFENCE在处理器x86/x86_64中是否有任何意义上的指令?

回答:

1. …

x86 assembly x86-64 atomic memory-barriers

40
推荐指数
2
解决办法
1万
查看次数

原子变量是否无锁?

当我们谈论原子变量时,例如C++ 11 atomic<>,它是否可以免费锁定?或者锁定是不同的东西?如果我使用原子变量管理队列,它会比无锁队列慢吗?

c++ multithreading x86-64 atomic c++11

39
推荐指数
2
解决办法
1万
查看次数

初始化std :: atomic_bool?

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

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

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

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

39
推荐指数
3
解决办法
4万
查看次数