首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >子函数中的内存栅栏与与数据变化相同的函数中的内存围栏

子函数中的内存栅栏与与数据变化相同的函数中的内存围栏
EN

Stack Overflow用户
提问于 2015-04-30 21:00:47
回答 1查看 67关注 0票数 0

如果我在子函数中放置内存栅栏,而不是在使用数据的函数中放置内存围栏,那么线程安全性是否存在差异。下面的示例包括这两个版本。我想知道是否有我不知道的分歧。函数A_functionB_function是否都是线程安全?

代码语言:javascript
运行
复制
#include<atomic>

using std::atomic;
using std::atomic_thread_fence;
using std::memory_order_acquire;
using std::memory_order_release;

typedef struct 
{
    atomic<int> lock;
    int counter;
}Data;

void A_acquire(atomic<int> * lock);
void A_release(atomic<int> * lock);
void A_function(Data * data);
void B_acquire(atomic<int> * lock);
void B_release(atomic<int> * lock);
void B_function(Data * data);

void A_acquire(atomic<int> * lock)
{
    int ticket = lock->fetch_add(1);
    while (0 != ticket)
    {
        lock->fetch_sub(1);
        ticket = lock->fetch_add(1);
    }
    //DIFFERENCE HERE
}

void A_release(atomic<int> * lock)
{
    //DIFFERENCE HERE
    lock->fetch_sub(1);
}

void A_function(Data * data)
{
    A_acquire(&data->lock);
    atomic_thread_fence(std::memory_order_acquire); //DIFFERENCE HERE
    data->counter += 1;
    atomic_thread_fence(std::memory_order_release); //DIFFERENCE HERE
    A_release(&data->lock);
}

void B_acquire(atomic<int> * lock)
{
    int ticket = lock->fetch_add(1);
    while (0 != ticket)
    {
        lock->fetch_sub(1);
        ticket = lock->fetch_add(1);
    }
    atomic_thread_fence(std::memory_order_acquire); //DIFFERENCE HERE
}

void B_release(atomic<int> * lock)
{
    atomic_thread_fence(std::memory_order_release); //DIFFERENCE HERE
    lock->fetch_sub(1);
}

void B_function(Data * data)
{
    B_acquire(&data->lock);
    //DIFFERENCE HERE
    data->counter += 1;
    //DIFFERENCE HERE
    B_release(&data->lock);
}

int main(void)
{
    Data dat = { 0, 0 };
    A_function(&dat);
    B_function(&dat);
    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-30 22:32:12

A_functionB_function在语义上没有区别。记忆栅栏效应不受函数体的限制。

另外,正如幻影所指出的,在您的示例中,内存围栏是不必要的:fetch_sub()fetch_add()都已经获得+发布语义。

但是通过下面的修改,版本获取变得非常重要:

代码语言:javascript
运行
复制
void A_acquire(atomic<int> * lock)
{
    int ticket = lock->exchange(1);
    while (0 != ticket)
    {
        ticket = lock->exchange(1);
    }
    //DIFFERENCE HERE
}

void A_release(atomic<int> * lock)
{
    //DIFFERENCE HERE
    lock->store(0, memory_order_relaxed);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29977679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档