c – 内存障碍:工作线程如何确保初始化写入?
我对使用内存屏障/栅栏进行编程是相当新的,我想知道如何保证设置写入在随后在其他CPU上运行的工作器函数中可见.例如,请考虑以下事项:
int setup,sheep; void SetupSheep(): // Run once CPU 1: setup = 0; ... much later CPU 1: sheep = 9; CPU 1: std::atomic_thread_fence(std::memory_order_release); CPU 1: setup = 1; 之后(不是同时)运行很多次: void ManipulateSheep(): CPU 2: int mySetup = setup; CPU 2: std::atomic_thread_fence(std::memory_order_acquire); CPU 2: // Use sheep... 在CPU 2上,如果mySetup是1,那么羊肯定是9 – 但是我们怎样才能保证mySetup不为0? 到目前为止,我所能想到的是在CPU 2上旋转等待直到设置为1.但是这看起来非常难看,因为旋转等待只需要在第一次调用ManipulateSheep()时等待.当然必须有更好的方法吗? 请注意,未初始化代码也存在对称问题:假设您正在编写一个无锁数据结构,该结构在其生命周期内分配内存.在析构函数中(假设所有线程都已完成调用方法),您希望释放所有内存,这意味着您需要运行析构函数的CPU具有最新的变量值.在这种情况下甚至不可能旋转等待,因为析构函数无法知道“最新”状态是什么,以便检查它. 编辑:我想我要问的是:有没有办法说“等待所有商店传播到其他CPU”(用于初始化)和“等待所有商店传播到我的CPU”(用于未初始化)? 解决方法
事实证明,#StoreLoad正是这种情况的正确障碍.
As explained simply by Jeff Preshing:
在C 11中,std :: atomic_thread_fence(std :: memory_order_seq_cst)显然充当#StoreLoad屏障(以及其他三个:#StoreStore,#LoadLoad和#LoadStore).见this C++11 draft paper. 附注:在x86上, 因此,无锁代码的模式可能是: Initialize: CPU 1: setupStuff(); CPU 1: std::atomic_thread_fence(std::memory_order_seq_cst); Run parallel stuff Uninitialize: CPU 2: std::atomic_thread_fence(std::memory_order_seq_cst); CPU 2: teardownStuff(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |