c++ - C++多线程设置中服务器重新初始化的良好设计

标签 c++ multithreading c++11

我们正在开发一个带有 C 接口(interface)的 C++ 库。在C接口(interface)中,有:

  • 初始化库的函数(Init() - 构造使用给定参数实现功能的对象);
  • 取消初始化库的函数(DeInit() - 销毁该对象),以及;
  • 几个仅调用对象上相应方法的函数(例如 Foo()Bar() )。

类本身是线程安全的,但我希望 C 接口(interface)(即 Init()DeInit()Foo()Bar() )也是线程安全的。

有一个全局变量——指向类实例的指针。您认为以下哪种方法最好?你会用不同的方式来做吗?

  1. 有一个全局 unique_ptr<T>以及全局读/写锁。 Foo()Bar()锁定以供阅读; Init()DeInit()锁定它以便写入。
  2. 使用信号量来跟踪使用实例的线程数。如果DeInit()被调用时,等待信号量直到其计数为 0。
  3. 使用shared_ptr语义。全局shared_ptr可以更改,但对象不会被删除,直到没有用户为止。这有可能使系统过载,因为可能有多个实例(消耗大量内存)来满足挂起操作的需求,因为 Init() 不会(也不需要)等到挂起操作完成.

选项 3 似乎最容易使用 C++11 实现。如果我错了或太模糊,请纠正我。

编辑 说明:对 Init() 和 DeInit() 的调用正在更改全局指针,因此应通过锁来防止它们同时运行。 Foo() 和 Bar() 应该能够同时运行。

编辑澄清 通过 C 接口(interface),我指的是实现 C 接口(interface)的函数集。我希望这组函数是线程安全的。

最佳答案

通常,如果可能的话,应该避免使用全局变量,即使是隐藏变量。由于您的类已经是线程安全的,因此可以通过将句柄返回给用户来完全消除锁定。他们最有资格知道该怎么做。然后编写好的文档并让用户决定同步什么以及如何同步。例如:

void *handle = Init(...);
void *value = Foo(handle, ...);
int status = Bar(handle, ...);
DeInit(handle, ...);

如果库用户代码是用 C++ 编写的,那么将其包装到具有同步访问(如果需要)的 C++ 智能处理程序类中是很简单的。如果用户以某种方式知道永远不会发生并发访问(例如,用户代码可能在单个线程中运行),则无需锁定任何内容。

[编辑:错别字]

关于c++ - C++多线程设置中服务器重新初始化的良好设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18400172/

相关文章:

c++ - volatile 变量被优化掉了吗?

c - 为什么 4 线程程序在 1 核 VM 上比在 4 核 VM 上运行得更快?

C# 挂起线程直到服务器响应

c++ - std::function 检查类的继承

c++ - 使用 `-> decltype` 推断返回类型

c++ - 为什么 std::allocator::deallocate 不是 noexcept?

c# - c++ 中的 string* [] 转换为 c# 中的 string[]

c++ - 在 c++ 中构建和运行 c++ -- c++ 脚本(而不是 lua)

c++ - 如何获取 std::vector<int>* 的值?

c++ - 如何在c++中的文件处理中删除文件