gpt4 book ai didi

c++ - 单个进程中有数千个读取器/写入器锁

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:53 29 4
gpt4 key购买 nike

我目前正在设计一个具有大规模同步模式的 C++ 跨平台 (Linux/Windows) 服务器应用程序。我在内部使用 boost::thread 作为操作系统特定线程的抽象。我的问题是保护数据数组,数组的每个元素都受到独立的读写器锁的保护

我的数组包含4096 个元素。考虑到“Little Book of Semaphores”(第 85 页)中提出的“写入者优先的读者-写入者”问题的解决方案,我的应用程序每个数组元素需要 5 个信号量。这给出了总共大约 20000 个信号量(或者,等效地,20000 个互斥锁 + 20000 个条件变量)。

我的应用程序的另一个特殊性是,在给定时间,大多数信号量都不活动(通常有大约 32 个“客户端”线程在数千个信号量上等待/发出信号)。请注意,由于整个服务器在单个进程中运行,因此我使用基于线程的轻量级信号量(不是进程间信号量)。

我的问题有两个:

  1. 是否建议为单个进程在 Linux 和 Windows 上创建总共 20000 个信号量?好吧,当然,我想情况并非如此......

  2. 如果不推荐这种做法,我可以使用什么技术来减少实际信号量的数量,例如在 1 个实际信号量的顶部创建一组 N 个“模拟信号量”?我想这将是一个有趣的解决方案,因为我的大部分信号量在给定时间都处于非事件状态。

提前致谢!

到目前为止的答案总结

  1. 不推荐使用数千个信号量,尤其是从跨平台的角度来看。因此,即使它们不是进程间信号量(它们在 Windows 下仍然使用句柄)。
  2. 解决我的问题的一个直接方法是将我的数组拆分成例如16 个元素的 64 个子数组,将这些子数组中的每一个与单个读/写锁相关联。不幸的是,这会引起很多争用(一位作者会阻止对 15 个元素的读取)。
  3. 深入研究 Boost 源代码,我发现:

    • “boost::mutex”的实现不在 Windows 下包装 CRITICAL_SECTION 对象(但 CreateEvent 和 ReadWriteBarrier),
    • “boost::shared_mutex”在 Windows 下使用 CreateSemaphore(这是重量级的进程间对象),并且
    • “boost::shared_mutex”在 Linux 下不包装“pthread_rwlock_t”。

    我似乎不太清楚其中的原因。特别是,在 Windows 下为“boost::shared_mutex”使用进程间对象对我来说似乎不是最佳选择。

目前开放问题的总结

  1. 如何在 1 个实际信号量的顶部创建一组 N 个“模拟信号量”,使模拟信号量之间的争用尽可能小?
  2. “boost::mutex”和“boost::shared_mutex”与其原生对应物(CRITICAL_SECTION 和 pthread_rwlock_t)相比如何?

最佳答案

  1. 不推荐这样做。你实际上不应该这样做,因为在 Windows 中,它会为每个信号量消耗 1 个句柄对象。一个过程只能管理特定数量的 Handles 对象。线程/进程和其他 Windows 对象可能需要使用 Handle 对象并将如果他们不能,就会崩溃。这在 Linux 中与文件描述符概念。

  2. 将您的 4096 个元素分成 30 个(例如)组,每组 140 个元素并为每个 140 组分配一个信号量。然后30(在此示例中)线程将尝试访问这 30 个集合,并且它们将根据每个 140 组信号量同步。

关于c++ - 单个进程中有数千个读取器/写入器锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6965688/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com