将pthread_mutex_t obj嵌入到C ++ obj实例中是一个好主意吗?我觉得(遗憾的是)没有蝙蝠

时间:2014-10-28 16:20:29

标签: c++ pthreads mutex

这个问题源于我通过pthread实现以下简单的邮箱界面:

typedef void* MailBox;

typedef enum MailBoxReturnValues {ok=0, fail4timeOut, fail} MailBoxReturnValues;


MailBox              CreateMailBox (const char* const mailBoxName);  /* returns NULL 4 fail */

MailBoxReturnValues  DeleteMailBox (MailBox   mailBox);      
MailBoxReturnValues      TxMailBox (MailBox mbx, void*    sendingObj, unsigned timeoutInTic);
MailBoxReturnValues      RxMailBox (MailBox mbx, void* *receivingObj, unsigned timeoutInTic);

为了实现它,我创建了一个C ++类,其中我放置了所有的suff,还有一个互斥体,它必须序列化对每个实例的访问。当我尝试编写DeleteMailBox时,问题就出现了,因为我无法删除锁定的互斥锁,但如果我解锁它,我无法保证其他人可以访问删除对象。 (在我看来,锁定互斥锁的线程也必须有可能删除它。)

1 个答案:

答案 0 :(得分:3)

销毁应始终在外部同步。互斥体(或任何本质上同步的对象)永远不能同步它自己的破坏。

您担心的竞争是两个线程可能同时在同一个DeleteMailBox对象上调用TxMailBoxMailBox。正如您所观察到的,MailBox对象本身无法防范此种族。即使你可以销毁一个锁定的互斥锁,另一个线程的并发锁定尝试现在会尝试锁定一个被破坏的互斥锁,这是一个数据竞争。

这是多线程上下文中面向对象设计的基本限制。如果用户请求销毁对象,则由用户确保没有人会尝试从该点开始同时访问该对象。

请注意,此上下文中的 user 可以是任何外部实体。例如,在C ++ 11中,您经常可以使用weak_ptr来解决此问题。但原则上这仍然是一个非常重要的问题,需要仔细考虑。