在信号量上调用的WaitForSingleObject失败,最后一个错误为183(ERROR_ALREADY_EXISTS)

时间:2014-06-26 15:49:17

标签: c++ multithreading winapi semaphore

我正在尝试为生产者 - 消费者风格的任务编写一个BlockingQueue类。我正在使用WinAPI,但我遇到WaitForSingleObject的问题。当我在信号量上用值0调用它时,它不是睡着而是返回-1(WAIT_FAILED)而GetLastError()给出183(ERROR_ALREADY_EXISTS)。这让我没有意义,所以我认为我必须做一些非常错误的事情。该方法出现问题的方式如下:

template<typename elem_t>
elem_t BlockingQueue<elem_t>::pop() {

    WaitForSingleObject(_used_sem, INFINITE);
    WaitForSingleObject(_mutex, INFINITE);
    uint first = _first;
    if (++_first == _length)
        _first = 0;
    _count--;
    ReleaseMutex(_mutex);
    ReleaseSemaphore(_free_sem, 1, NULL);
    return _data[first];

}

信号量和互斥量都在构造函数中初始化:

template<typename elem_t>
BlockingQueue<elem_t>::BlockingQueue(uint length) {

    _data = new elem_t [length];
    _length = length;
    _count  =  0;
    _first  =  0;
    _last   = -1;
    _mutex    = CreateMutex(NULL, false, NULL);
    _free_sem = CreateSemaphore(NULL, _length, INFINITE, NULL);
    _used_sem = CreateSemaphore(NULL, _count,  INFINITE, NULL);

}

为什么我会收到如此奇怪的错误?

编辑:错误183是由于错误检查错误,因为它在调用GetLastError()之前被另一个错误覆盖。在纠正之后,它只是6(ERROR_INVALID_HANDLE),更有意义。

1 个答案:

答案 0 :(得分:4)

您没有检查CreateSemaphore的返回值。它可能在这种情况下失败,或者如果它成功,它正在创造一个不可能的&#34;信号。这是因为您使用INFINITE作为最大计数参数。最大计数参数是有符号长整数,INFINITE用于无符号毫秒持续时间,如果将其解释为带符号的LONG值,则最终为-1。文档说明最大计数值必须大于0.在创建信号量时使用LONG_MAX而不是INFINITE。