2

我正在开发一个具有多个线程和一个共享对象的系统。有许多线程经常执行读取操作,但写入操作很少,每天可能 3 到 5 次。

我正在使用 rwlock 进行同步,但是锁获取操作不够快,因为它一直在发生。所以,我正在寻找一种更快的方法。

也许是一种使写入函数原子化或在写入期间查看所有线程的方法。可移植性这不是硬性要求,我使用的是带有 GCC 4.6 的 Linux。

4

3 回答 3

5

您是否考虑过将 read-copy-update 与liburcu一起使用?这使您可以避免原子操作并完全锁定在读取路径上,但代价是写入速度要慢一些。请注意,一些读者可能会在短时间内看到陈旧的数据;如果您需要更新立即生效,它可能不是您的最佳选择。

于 2012-04-28T21:12:04.220 回答
4

您可能想要使用多个对象而不是单个对象。与其实际共享对象,不如创建一个包含对象和原子计数的对象,然后在线程之间共享指向该结构的指针。

【假设只有一个写者】每个读者都会得到指针,然后原子地递增计数器并使用对象,读完后原子地递减计数器。作者将创建一个包含原始副本的新对象并对其进行修改。然后执行两个指针的原子交换。现在问题是释放旧对象,这就是为什么你需要读者的数量。作者需要继续检查旧对象的计数,直到所有读者都完成了工作,此时您可以删除旧对象。

如果有多个写入器(即可以有多个线程更新变量),您可以采用相同的方法,但写入器需要对指针进行比较和交换交换。如果更新副本的指针已更改,则写入器重新启动进程(删除它的新对象,再次从指针复制并重试 CAS)

于 2012-04-28T19:04:53.363 回答
1

也许您可以使用自旋锁,线程将忙于等待解锁。如果线程没有长时间锁定,它可能比互斥锁更有效,因为锁定和解锁是用更少的指令完成的。

spinlock 是 POSIX pthread 的一部分,虽然是可选的,所以我不知道它是否在您的系统上实现。我在 ubuntu 上的 C 程序中使用了它们,但必须使用 -std=gnu99 而不是 c99 进行编译。

于 2012-04-29T01:55:59.747 回答