您已经开发了一个示例代码来实现。多个生产者和单个消费者问题。
我已经占用了一个队列而且我已经限制了20的大小。所以我使用信号量和CrticalSection(windows api)来保护它。如果超过20个线程队列它就不会被允许。信号量应该保护它
我有两个方法AdddTail(在队列中添加msg)和Remove Head(从队列中删除msg)方法来操作队列。
我收到错误发布信号量太多帖子。我不明白这个问题。 我有20个生产者线程,等待8000毫秒,一个消费者线程,4000毫秒等待。 我认为ReleaseSemaphore会导致问题。
BOOL CEventQueue::AddTail(LPVOID p)
{
BOOL result;
char* pMsg = (char*)p;
char* pMsg1 = new char[100];
int nOffset = strlen(pMsg);
strcpy(pMsg1,pMsg);
strcat(pMsg1," Waiting");
PostMessage(hWnd,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0);
DWORD dwWaitResult = WaitForSingleObject(handles,INFINITE);
switch(WAIT_OBJECT_0)
{
case WAIT_OBJECT_0:
{
::EnterCriticalSection(&m_QueueLock);
queue.AddTail(p);
::LeaveCriticalSection(&m_QueueLock);
result = ::ReleaseSemaphore(handles[SemaphoreIndex],1, NULL);
}
break;
case WAIT_TIMEOUT:
return 0;
break;
}
if(!result)
{ /* failed */
// caller can use ::GetLastError to determine what went wrong
queue.RemoveTail();
ErrorExit(_T("AddTail"));
} /* failed */
return result;
} // AddTail
LPVOID result;
switch(::WaitForMultipleObjects(2, handles, FALSE, INFINITE))
{
/* decode */
case StopperIndex: // shut down thread
::ExitThread(0); // kill thread
return NULL; // return keeps C compiler happy
case SemaphoreIndex: // semaphore
::EnterCriticalSection(&m_QueueLock);
result = queue.RemoveHead();
::LeaveCriticalSection(&m_QueueLock);
return result;
case WAIT_TIMEOUT: // not implemented
default:
ASSERT(FALSE); // impossible condition
return NULL;
//::ReleaseSemaphore(handles[SemaphoreIndex],1, NULL);
} /* decode */
答案 0 :(得分:2)
将WaitForSingleObject(handles,INFINITE)
更改为WaitForSingleObject(handles[SemaphoreIndex],INFINITE)
。
将switch(WAIT_OBJECT_0)
更改为switch(dwWaitResult)
,并为此切换添加错误处理。
case StopperIndex:
应该是StopperIndex + WAIT_OBJECT_0:
个案例,对case SemaphoreIndex:
应用相同的更改
将编译器警告级别调到最大,并修复它所警告的内容。
正确的操作顺序是:
制作人:锁定关键部分,添加到队列,释放关键部分,释放信号量。
消费者:等待信号量,锁定关键部分,从队列中获取,释放关键部分。
您的代码似乎等待生产者和消费者中的信号量,这将导致死锁。