gpt4 book ai didi

c++ - 在多线程 C++ 服务器应用程序中处理非常量全局配置

转载 作者:搜寻专家 更新时间:2023-10-31 00:00:42 25 4
gpt4 key购买 nike

我正在设计一个多线程的 C++ 服务器应用程序,它在自己的线程中为客户端提供服务,并且还有各种其他工作线程来执行其他任务。

所有这些线程都将依赖于一个文本配置文件,该文件需要能够在不退出和重新启动进程的情况下重新散列。

我目前正在考虑让每个客户端和工作线程都有自己的配置对象拷贝,然后在每次重新哈希时进行此更新。

我发现的一件事是将配置传递给所有其他我更喜欢但不认为应该是上述类的一部分的实用函数似乎变得非常乏味.

除了需要大量同步的痛苦之外,拥有全局配置会容易得多。

欢迎任何关于如何解决线程应用程序中具有非常量全局配置的想法!

最佳答案

我喜欢这样做的方式是始终将配置作为 shared_ptr 传递给 const 对象。每当您需要配置时(记住一致性;通常最好使用相同的配置处理整个请求,即使配置在请求处理代码的末尾在技术上已经过时),您会得到一个 shared_ptr 到它。后台工作任务可以在工作周期中的方便点重置其 shared_ptr 的值,尽量避免持有配置太久(因为它可能会过时)。

如果只有一个任务可以改变配置,这很好用;它构造一个全新的配置对象,然后重置它的 shared_ptr,[编辑]它用锁保护它,见下文[/编辑]。一旦没有其他任务使用旧配置对象,旧配置对象就会消失。

一个细节:你不能传递指向部分配置对象的指针,除非你确定你将持有指向该配置对象的 shared_ptr,只要指针会持续下去。如果配置包含例如名称到子配置的映射,这可能会令人恼火。

虽然共享指针有一些开销,但它可能比保持配置的整个拷贝同步要少(当然,除非配置很小,否则我们可能不会进行此对话)。在大多数应用程序中,配置更改相对较少,因此您不太可能在任何给定时间拥有两个以上的配置对象。您通常可以安排为每个请求创建一个 shared_ptr,因此 shared_ptr 同步是微不足道的。

YMMV,但我发现效果很好。

[编辑] 正如一些评论者所指出的,我应该明确说明锁定要求。配置更新器保留一个受读写锁保护的主 shared_ptr。它在更新指针时需要持有写锁。它还导出一个接口(interface),该接口(interface)将 shared_ptr 返回到当前配置;该接口(interface)在持有读锁的同时复制 shared_ptr。由于配置更改很少见且 shared_ptr 很小,因此几乎没有锁争用。[1]

除了配置任务本身,没有其他人需要担心锁,因为其他 shared_ptr 不应该被多个任务共享:每个任务都应该有自己的。

[1] 当我写这篇文章时,我意识到我一直这样做的方式,包括在主 shared_ptr 上调用 .reset,如果配置的析构函数很慢(例如,如果配置包含大量 std::string,则可能)。最好扩展 reset 的实现(它只是一个带有临时 NULL shared_ptr 的交换),将交换放在锁保护器中并让(临时的)析构函数解锁运行。然而,考虑到配置更改是多么罕见(至少在我与之相关联的任何服务器中),我怀疑它是否会产生任何明显的差异。

关于c++ - 在多线程 C++ 服务器应用程序中处理非常量全局配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12488733/

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