对信号量进行了太多帖子
Posted
技术标签:
【中文标题】对信号量进行了太多帖子【英文标题】:Too many Post were made to semaphore 【发布时间】:2011-03-07 09:36:52 【问题描述】:您好已经开发了一个示例代码来实现。多生产者和单消费者问题。
我已经使用了一个队列,并且我将队列的大小限制为 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 */
【问题讨论】:
【参考方案1】:将WaitForSingleObject(handles,INFINITE)
更改为WaitForSingleObject(handles[SemaphoreIndex],INFINITE)
。
将switch(WAIT_OBJECT_0)
更改为switch(dwWaitResult)
并将错误处理添加到此开关。
case StopperIndex:
应为StopperIndex + WAIT_OBJECT_0:
,对case SemaphoreIndex:
应用相同的更改
把你的编译器警告级别调到最高,并修复它的警告。
正确的操作顺序是:
生产者:锁定临界区,加入队列,释放临界区,释放信号量。
消费者:等待信号量,锁定临界区,从队列中取出,释放临界区。
您的代码似乎在等待生产者和消费者中的信号量,这会死锁。
【讨论】:
我如前所述更改了它,但现在所有线程都在 WaitForSingleObject(handles[SemaphoreIndex],INFINITE) 处被阻塞。它们永远不会超出此范围以上是关于对信号量进行了太多帖子的主要内容,如果未能解决你的问题,请参考以下文章