如何扩展OpaqueObject的并发防护机制至deallocateObject函数?
如何为
deallocateObject()扩展并发安全防护? 先看我们内部基于C++实现的C API:
struct OpaqueObject; struct OpaqueObject *allocateObject(); int deallocateObject(struct OpaqueObject *obj); int useObject(struct OpaqueObject *obj);
这里的并发规则是:多个不同的struct OpaqueObject实例可以安全地并发分配、使用和释放,但同一实例的并发调用是不允许的,会导致未定义行为。
为了防止同一实例被并发调用useObject(),我们在struct OpaqueObject里加了一个互斥锁,当多个线程尝试调用同一实例的useObject()时,函数会直接返回错误码:
struct OpaqueObject { std::mutex access; // ... 其他成员变量 }; int useObject(struct OpaqueObject *obj) { if (!obj->access.try_lock()) { // 当前有其他线程在使用该实例 return CONCURRENT_USE_ERROR; } else { // 开始使用实例的业务逻辑 // ... obj->access.unlock(); return OK; } }
现在的问题是,怎么把这个防护机制扩展到deallocateObject()函数上?一开始我想到的简单实现是这样的:
int deallocateObject(struct OpaqueObject *obj) { if (!obj->access.try_lock()) { // 当前有其他线程在使用该实例 return CONCURRENT_USE_ERROR; } else { delete obj; // <--- (1) return OK; } }
但这里有个致命问题:销毁处于锁定状态的互斥锁属于未定义行为。可如果在(1)行之前解锁互斥锁,那我们防止并发使用和释放的防护就完全失效了——解锁后到delete之前,别的线程可能会调用useObject()拿到锁,然后我们delete了实例,直接触发未定义行为。
所以想请教大家:当同一struct OpaqueObject实例被并发调用useObject()和deallocateObject()时,有没有办法让其中任意一个函数返回错误?
内容的提问来源于stack exchange,提问作者phlipsy
相关产品推荐
相关产品推荐

