我正在尝试为生产者 - 消费者风格的任务编写一个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),更有意义。
答案 0 :(得分:4)
您没有检查CreateSemaphore的返回值。它可能在这种情况下失败,或者如果它成功,它正在创造一个不可能的&#34;信号。这是因为您使用INFINITE
作为最大计数参数。最大计数参数是有符号长整数,INFINITE用于无符号毫秒持续时间,如果将其解释为带符号的LONG值,则最终为-1。文档说明最大计数值必须大于0.在创建信号量时使用LONG_MAX而不是INFINITE。