三十部分库中的线程安全性
thread safety in thirty part libraries
我想使用别人开发的库,我只有库文件,没有源代码。我的问题是:库为类提供了许多功能。类本身不是线程安全的。我想让它线程安全,我想知道这个代码是否工作
// suppose libobj is the class provided by the library
class my_libobj : public libobj {
// code
};
这只继承自libobj
,它可能"工作",也可能"不工作",这取决于类是否是为继承而设计的(至少有一个virtual
析构函数(。
无论如何,它不会为你免费购买螺纹安全。最简单的方法是向类中添加互斥对象,并在进入关键部分时锁定这些互斥对象:
class my_obj {
libobj obj; // inheritance *might* work too
boost::mutex mtx;
void critical_op()
{
boost::unique_lock lck(mtx);
obj.critical_op();
}
};
(这是一个非常粗粒度的设计,只有一个互斥;如果你知道各种操作的行为,你可能会使它变得更细粒度。正如@dribeas所解释的,它也不是傻瓜式的。(
在一个尚未设计的库中改造线程安全性和BTW,有不同的级别,如果你不满足于序列化对它的所有调用,那么在不知道它是如何实现的情况下,可能是不可能的,即使这样,如果接口足够糟糕,也可能会有问题——例如,请参阅strtok。
如果不了解,这是不可能回答的,至少是类的实际接口。一般来说,答案是否定的。
从实用C++的角度来看,如果该类不是为扩展而设计的,那么每个非虚拟方法都不会被覆盖,因此您可能会得到一些线程安全和非线程安全方法的混合。
即使您决定只在持有锁的情况下进行包装(无继承(并强制委派,这种方法仍然不是在所有情况下都有效。线程安全不仅需要锁定,还需要一个可以实现线程安全的接口。
考虑一下STL中的stack
实现,只需添加一层锁定(即使每个方法都是线程安全的(,就不能保证容器上的线程安全。考虑一下几个线程向堆栈中添加元素,两个线程提取信息:
if ( !stack.empty() ) { // 1
x = stack.top(); // 2
stack.pop(); // 3
// operate on data
}
这里可能会出现很多错误:当堆栈中只有一个元素时,两个线程可能都会执行测试[1],然后按顺序输入,在这种情况下,第二个线程将在[2]中失败(或获得相同的值,但在[3]中失败(,即使在容器中有多个对象的情况下,这两个线程都可以在执行[3]之前执行[1]和[2],在这种情况下,两个线程将使用相同的对象,堆栈中的第二个元素将被丢弃而不进行处理。。。
线程安全需要(在大多数情况下(更改API,在上面的示例中,提供实现为:的bool pop( T& v );
的接口
bool stack::try_pop( T& v ) { // argument by reference, to provide exception safety
std::lock<std:mutex> l(m);
if ( s.empty() ) return false; // someone consumed all data, return failure
v = s.top(); // top and pop are executed "atomically"
s.pop();
return true; // we did consume one datum
}
当然,还有其他方法,您可能不会返回失败,而是等待pop
操作中的一个条件,该条件通过使用条件变量或类似的东西来保证锁定,直到数据准备就绪。。。
最简单的解决方案是为该库创建一个唯一的线程,并仅从该线程访问该库,使用消息队列传递请求和返回参数。
- 类与私有变量的其他类之间的线程安全性
- 调用socket.remote_endpoint(提升 asio 库)线程安全性
- std::lock_guard 似乎提供了线程安全性,尽管作用域块
- C++中向量和列表的非写入成员函数的线程安全性
- 线程安全性和静态变量/成员功能
- 是仅使用get或toplown的原始类型的线程安全性的威胁
- 提高 ASIO stream_descriptor和事件 FD 线程安全性
- OpenMP中树结构的线程安全性
- 静态变量初始化的线程安全性
- 从另一个(非 qt)线程调用 QObject 方法的线程安全性?
- C 共享_ptr如何确保线程安全性
- 编写std::vector与普通数组的线程安全性
- C++标准库容器相对于所包含对象的线程安全性
- 读取和写入操作的线程安全性C++
- Qt库-静态成员函数的线程安全性
- QObject可重入性和线程安全性
- std::map中的线程安全性
- boost::asio io_service 和 std::containers 的线程安全性
- C++11 std:原子<T>复制构造函数的线程安全性
- Clang 线程安全性分析和线程角色