我可以在线程A中使用EnterCriticalSection(s),然后在线程B中使用LeaveCriticalSection(s)吗?

时间:2016-11-29 18:16:59

标签: c++ windows c++11

所以我有SEND_SLOT结构:

struct SEND_SLOT
{
    SEND_BUFFER buffer;
    uint16 index;
    CRITICAL_SECTION slotLock;
};

和连接结构:

struct connexion
{
    ...
    SEND_SLOT sendSlots[3];
    ...
}

在线程A中我做:

if(TryEnterCriticalSection(&sendSlots[i]))
{  //Post send request...
   WSASend(...);
}

并在线程B中执行:

while(...)
{
   ...
   //request finished, data sent, and i get the index to the SEND_SLOT
   LeaveCriticalSection(&sendSlots[index]);
   ...
}

所以我试图锁定线程A中的SEND_SLOT i,后来我想要解锁它,可能来自另一个线程,但它不能正常工作,每次我尝试发布新发送时它锁定第一个插槽即使哈希已经被锁定,并且没有发出LeaveCriticalSection。为什么?

1 个答案:

答案 0 :(得分:6)

不,这不合法。 documentation for LeaveCriticalSection解释了调用EnterCriticalSection的同一个帖子也必须调用LeaveCriticalSection

  

线程使用EnterCriticalSectionTryEnterCriticalSection函数获取关键部分对象的所有权。要释放其所有权,线程必须在每次进入关键部分时调用LeaveCriticalSection一次。

     

如果线程在没有指定的临界区对象的所有权时调用LeaveCriticalSection,则会发生错误,导致使用EnterCriticalSection的另一个线程无限期地等待。

同样的限制适用于互斥锁。对于您的情况,信号量更合适。 MSDN

  

只有拥有互斥锁的线程才能成功调用ReleaseMutex函数,但任何线程都可以使用ReleaseSemaphore来增加信号量对象的数量。