C++11 Concurrency Tutorial – Part 4: Atomic Types

In the previous article, we saw advanced techniques about mutexes. In this post, we will continue to work on mutexes with more advanced techniques. We will also study another concurrency technique of the C++11 Concurrency Library: Atomic Types


Atomic Types

We will take, the example of a Counter:

struct Counter {
    int value;

    void increment() {
        ++value;
    }
    void decrement() {
        --value;
    }
    int get(){
        return value;
    }
};

We already saw that this class was not safe at all to use in multithreaded environment. We also saw how to make if safe using mutexes. This time, we will see how to make it safe using atomic types. The main advantage of this technique is its performance. Indeed, in most cases, the std::atomic operations are implemented with lock-free operations that are much faster than locks.

The C++11 Concurrency Library introduces Atomic Types as a template class: std::atomic. You can use any Type you want with that template and the operations on that variable will be atomic and so thread-safe. It has to be taken into account that it is up to the library implementation to choose which syncronization mechanism is used to make the operations on that type atomic. On standard platforms for integral types like int, long, float, … it will be some lock-free technique. If you want to make a big type (let’s saw 2MB storage), you can use std::atomic as well, but mutexes will be used. In this case, there will be no performance advantage.

The main functions that std::atomic provide are the store and load functions that atomically set and get the contents of the std::atomic. Another interesting function is exchange, that sets the atomic to a new value and returns the value held previously. Finally, there are also two functions compare_exchange_weak and compare_exchance_strong that performs atomic exchange only if the value is equal to the provided expected value. These two last functions can be used to implement lock-free algorithms.

std::atomic is specialized for all integral types to provide member functions specific to integral (like operators ++, –, fetch_add, fetch_sub, …).

It is fairly easy to make the counter safe with std::atomic:

struct AtomicCounter {
    atomic<int> value;

    AtomicCounter() : value(0) {}
    void increment() {
        ++value;
    }
    void decrement() {
        --value;
    }
    int get() {
        return value.load();
    }
};
If you test this counter, you will see that the value is always the expected one.


Wrap-Up

In this article we saw a very elegant technique to perform atomic operations on any type. I advice you to use std::atomic any time you need to make atomic operations on a type, especially integral types.


Next

In the next post of this series, we will see how to use the Futures facility to perform asynchronous task.


from http://www.baptiste-wicht.com/2012/07/c11-concurrency-tutorial-part-4-atomic-type/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值