Windows条件变量在预期时未发出信号

时间:2015-07-03 13:03:17

标签: c++ multithreading winapi

我正在为内存缓冲区编写代码,允许线程相互共享内存。我正在尝试使用关键部分和条件变量进行同步。

这是我的源代码:

    size_t ReadBuffer(char *dst_buffer)
{
    size_t size = 0;
    EnterCriticalSection(&m_CriticalSection);

    if (!m_bBufferReady)
    {
        printf("ReadBuffer: wait for ready buffer\n");   
        SleepConditionVariableCS (&BufferNotEmpty, &m_CriticalSection, INFINITE);
        printf("ReadBuffer: after wait for ready buffer\n"); 
    }
    if (m_uRealSize == 0)
    {

    }
    memcpy(dst_buffer, m_pBuffer, m_uRealSize);
    size = m_uRealSize;
    m_uRealSize = 0;
    m_bBufferReady = FALSE;
    LeaveCriticalSection(&m_CriticalSection); 
    WakeConditionVariable (&BufferNotFull);
    if (size != 0)
    {
        SleepConditionVariableCS (&BufferNotEmpty, &m_CriticalSection, INFINITE);
    }

    return size;
}

size_t WriteBuffer(const char *src_buffer, size_t size)
{
    EnterCriticalSection(&m_CriticalSection);
    if (m_bBufferReady)
    { 
        SleepConditionVariableCS (&BufferNotFull, &m_CriticalSection, INFINITE);
        printf("WriteBuffer: after wait for free buffer\n"); 
    }
    if (size > m_uBufferSize)
        size = m_uBufferSize;
    memcpy(m_pBuffer, src_buffer, size);
    m_uRealSize = size;
    m_bBufferReady = TRUE;
    LeaveCriticalSection(&m_CriticalSection); 
    WakeConditionVariable (&BufferNotEmpty);
    SleepConditionVariableCS (&BufferNotFull, &m_CriticalSection, INFINITE);
    return size;
}

当使用零大小缓冲区调用WriteBuffer时,它被视为通信结束。此时读取线程正确退出,但写入线程在最后一次调用SleepConditionVariableCS时挂起。

当我使用Windows事件而不是条件变量时,一切正常,所以我不认为这是算法的问题。但我希望能够使用条件变量而不是事件。对条件变量的使用有一些限制吗?或者它可能以某种方式连接到关键部分?

出了什么问题,我该如何解决?

1 个答案:

答案 0 :(得分:0)

我认为第一个问题是您在退出关键部分后调用SleepConditionalVariableCS。

来自documentation for SleepConditionVariableCS

  

调用SleepConditionVariableCS时,调用者必须输入一个关键部分。

documentation for LeaveCriticalSection中所述,退出您不拥有的关键部分会导致错误,导致另一个使用EnterCriticalSection的线程无限期地等待#34;。