最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Has counting_semaphore<X>::acquire a barrier? - Stack Overflow

programmeradmin3浏览0评论

Has counting_semaphore<X>::acquire() a barrier so that I won't need to have an atomic_thread_fence( memory_order_acquire ). The same would be nice for counting_semaphore<X>::relese( n ), which should include an atomic_thread_fence( memory_order_release ).

Has counting_semaphore<X>::acquire() a barrier so that I won't need to have an atomic_thread_fence( memory_order_acquire ). The same would be nice for counting_semaphore<X>::relese( n ), which should include an atomic_thread_fence( memory_order_release ).

Share Improve this question edited Mar 31 at 17:24 Nate Eldredge 59.4k6 gold badges71 silver badges113 bronze badges asked Mar 31 at 16:18 Edison von MyosotisEdison von Myosotis 6974 silver badges10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 5

These functions are acquire and release operations. They contain acquire and release barriers in the sense that acquire() will not be reordered with loads and stores that appear later in program order, and release() will not be reordered with loads and stores that appear earlier.

So for instance, if you do

int x;
std::counting_semaphore sem{0};
int not_atomic;
// thread 1
not_atomic = 47;
sem.release();
// thread 2
sem.acquire();
cout << non_atomic;

then this program does not have a data race, and it is guaranteed to print 47.

This is implied by [thread.sema.cnt p10] (N4860), which says about release():

Synchronization: Strongly happens before invocations of try_acquire that observe the result of the effects.

This also carries over to acquire and try_acquire_for, whose operations are defined as if by calling try_acquire.


However, this is not equivalent to placing a fence. For instance, a release fence would also prevent earlier loads and stores from being reordered with any later stores, not just with the sem.release() itself. Consider for instance

std::atomic<bool> flag{false};
// thread 1
not_atomic = 47;
std::atomic_thread_fence(std::memory_order_release);
flag.store(true, std::memory_order_relaxed);
// thread 2
if (flag.load(std::memory_order_acquire))
    cout << not_atomic;

This program is also free of data races and must print 47. But if you replace it with

// thread 1
not_atomic = 47;
sem.release();
flag.store(true, std::memory_order_relaxed);
// thread 2
if (flag.load(std::memory_order_acquire))
    cout << not_atomic;

then you have a data race. The relaxed store of flag can be reordered above sem.release(), at which point it can then be reordered above not_atomic = 47.

发布评论

评论列表(0)

  1. 暂无评论