我们正在开发一个带有 C 接口的 C++ 库。在C接口中,有:
- 一个初始化库的函数(
Init()
——用给定的参数构造实现功能的对象); - 一个取消初始化库的函数(
DeInit()
— 破坏该对象),以及; - 几个只调用对象上相应方法的函数(比如
Foo()
和Bar()
)。
类本身是线程安全的,但我希望 C 接口(即Init()
、DeInit()
和)Foo()
也是Bar()
线程安全的。
有一个全局变量——指向类实例的指针。您认为以下哪种方法最好?你会以不同的方式来做吗?
- 有一个全局
unique_ptr<T>
和一个全局读/写锁。Foo()
并Bar()
锁定阅读;Init()
并将DeInit()
其锁定以进行写入。 - 使用信号量来跟踪使用实例的线程数。如果
DeInit()
被调用,则在信号量上等待,直到其计数为 0。 - 使用
shared_ptr
语义。全局shared_ptr
可以更改,但在没有用户之前不会删除对象。这有可能使系统过载,因为可能有多个实例(消耗大量内存)来满足挂起操作的需求,因为 Init() 不会(也不需要)等到挂起的操作完成.
选项 3 似乎最容易使用 C++11 实现。如果我错了或太模糊,请纠正我。
编辑澄清:对 Init() 和 DeInit() 的调用正在更改全局指针,因此应该通过锁定来防止它们同时运行。Foo() 和 Bar() 应该能够同时运行。
编辑说明 C 接口是指实现 C 接口的一组函数。我希望这组函数是线程安全的。