我可以将部分数据用作锁定吗?
Can I use part of my data as lock?
我有一个大数组(3E9元素)数据,我正在在多个线程中更新其值。我刚刚发现有种族条件。
我认为锁定整个功能是不必要的,因为元素彼此独立,可以同时安全完成data[1]
和data[234]
上的更新。
我还发现data[]
中每个元素中最重要的位永远不会使用。在该位上实现GCC Atomic内置锁是否安全?
我的代码如下,但似乎正在发生僵局。
const unsigned short LOCK_MASK = 1<<15;
unsigned short * lock = &(data[position]);
unsigned short oldLock, newLock;
//lock
do {
oldLock = *lock;
newLock = oldLock ^ LOCK_MASK;
} while ((oldLock & LOCK_MASK) || !__sync_bool_compare_and_swap(lock, oldLock, newLock));
//update data[position] here
...
...
...
//unlock
*lock ^= LOCK_MASK;
我还阅读了这篇文章(由GCC原子操作构建的轻质自旋锁?),并在我的data
volatile
编辑在我的设计中,0表示解锁,1表示锁定
您的代码包含许多数据竞赛,包括oldLock = *lock
并解锁位*lock ^= LOCK_MASK
,由于没有发布障碍,这无法使您的更新与其他内核同步。
请注意,除了锁定数组段以进行写入访问之外,您还需要锁定该段以进行读取访问,因为必须同步读取和写入。
在该位上实现GCC Atomic内置锁是否安全?
如果要表达单独的状态进行读取和写入访问(解锁,锁定的X N,写锁定),则需要多个位。锁定到2个状态的单个位限制,锁定和解锁,它可以根据您的代码来实现:
const unsigned short LOCK_MASK = 1<<15;
void lock_array_segment(int position)
{
unsigned short *lock = &data[position]; // global array
unsigned short oldLock, newLock;
do {
oldLock = __atomic_load_n (lock, __ATOMIC_RELAXED);
newLock = oldLock | LOCK_MASK; // set bit
} while ((oldLock & LOCK_MASK) || !__sync_bool_compare_and_swap(lock, oldLock, newLock));
}
void unlock_array_segment(int position)
{
unsigned short *lock = &data[position]; // global array
unsigned short oldLock, newLock;
oldLock = __atomic_load_n (lock, __ATOMIC_RELAXED);
newLock = oldLock & ~LOCK_MASK; // clear bit
__atomic_store_n (lock, newLock, __ATOMIC_RELEASE);
}
在大多数情况下,__sync_bool_compare_and_swap
的文档说,这些内置被认为是完整的障碍。您需要在这里获得障碍,因此应涵盖。
由于您的方法是基于Spinlocking,因此如果您想将读书保留更长的时间,则无法正常工作。在这种情况下,考虑需要锁定的数据阵列中每个段的单独的segment使用单独的静音方法来考虑更直接的方法。如果要让多个阅读器访问,请考虑使用std::shared_mutex
(C 17)或boost::shared_mutex
。
您应该考虑更多的标准锁定方式(在C 11或更高)。
也许首先要阅读一些pthread教程(至少对于那里解释的概念)。
阅读有关C 中的原子操作和线程支持。
您可以在连续的1024(或两个其他功率)元素的每个段中考虑静音。
您可能会考虑一种生产者 - 消费者的方法。
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- C++ 11 中的锁定是否保证访问数据的新鲜度?
- 锁定的互斥锁是否保护condition_variable和数据?
- 我可以将部分数据用作锁定吗?
- 通知线程是否始终需要在修改期间锁定共享数据
- 试图更新和插入时,数据核心会被锁定
- 锁定免费的C++数据结构,不可能
- 在并发数据结构中,什么级别的锁定粒度是好的
- 在组合数据时不可能是恒定正确的,并且它是锁定的?
- 测试与C 原始数据类型上同步锁定的需求
- 互斥锁 / 什么是被锁定的互斥锁数据
- 我应该在多线程编程中始终锁定全局数据吗?为什么
- 为什么开发人员在多线程代码的读/写过程中锁定字长数据
- 是否可以使用互斥锁来锁定数据结构中的一个元素?
- 使用原子锁定自由的单生产者多消费者数据结构
- 树莓派从MPU6050+BMP180读取数据时锁定
- 在Linux上锁定对单个进程内数据访问的最快方法
- 如何锁定由属于两个不同类的两个线程修改的数据结构
- 是否有必要锁定STL容器以读取其数据?