2012-01-26 99 views
4

假设我们有一个大阵列和许多线程在该阵列中的具体索引上进行操作。两个线程不能同时在一个索引上运行,应该等到另一个索引完成。蹩脚的问题:如何在Linux/C/C++中实现对数组的每个索引锁定test-and-set细粒度锁定

+0

如何使用结构作为你的数组元素,所以每个元素都有数据和一些位用于锁定? – TJD 2012-01-26 23:04:51

+0

这可能会帮助你:http://stackoverflow.com/questions/3144349/boost-threads-mutex-array – 2012-01-26 23:35:35

回答

2

将数组元素类型设置为synchronized同步。如果你想要互斥你的数据,你可以有一个std::pair<T, std::mutex>;如果你可以在每次访问时使用自旋锁,你可以有一个std::pair<T, std::atomic<bool>>。然后让每个数组访问通过同步数据获得对元素的独占访问权。

3

您也需要一个简单的互斥锁,并做到:

mutex.lock(); 
    //access array using index 
    mutex.unlock(); 

或POSIX提供了一个读写锁。因此,你可以这样做:

和:对于读操作和写操作排它锁

pthread_rwlock_wrlock(rw_lock_ptr); 
    // update the array 
    pthread_rwlock_unlock(rw_lock_ptr); 

这允许共享锁。

我会建议你有一个类或对数组中的每个元素和实现上述之一。如果隐藏类的读取/更新函数中的互斥锁,则可以更容易地限制互斥锁的范围并轻松避免死锁。

4

对于细粒度锁定,请使用读/写锁定数组(如Carey Hickling所示)。对索引值进行散列并通过位掩码(或使用模数)对其进行筛选以选择要使用的锁。

这有效地将索引分成N个桶,其中N是您创建的锁的数量。对于容易掩蔽的位数,选择两个幂的次数(掩码= N - 1)。在这种情况下唯一的缺点是,你不只是锁定一个特定的索引,而是你锁定了每个索引,当哈希时,它们对齐到同一个锁定指针。这就是说,你创建的锁越多,锁的粒度越细(16可能是一个很好的起点)。读锁也与rw_locks共享,因此您只需要担心在写入期间等待锁。

+0

绝对的辉煌的解决方案,我来这里的想法,我将不得不使用一个锁阵列会限制每个元素的并行度或一个互斥量,这可能是一个巨大的锁。谢谢! – Aktau 2013-04-25 08:38:14