向信号量发送了太多帖子
您好,我们开发了一个示例代码来实现多个生产者和单个消费者问题。
我已经采取了一个队列,并将其大小限制为 20。所以我使用信号量和 CrticalSection(windows api)来保护它。如果超过 20 个线程,则队列将不会被允许。信号量应该保护它。
我有两个方法AdddTail(在队列中添加消息)和Remove Head(从队列中删除消息)方法来操作队列。
我收到错误向信号量发送了太多帖子。我不明白这个问题。 我有 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 */
Hi have developped an sample code to implement.Multiple producer and single consumer problem.
I have taken a Queue and I have restricted the size of the to 20.So I am using semaphore and CrticalSection (windows api)to protect it.If more than 20 thread the queue it wont be allowed.that semaphore should protect it.
I have two method AdddTail(add msg in queue) and Remove Head (remove msg from the queue)method to manipulate the queue.
I am getting Error Too many Post were made to semaphore.I dont understand the problem.
I have 20 Producer thread with 8000 ms waiting and one consumer thread with 4000 ms wating.
I think ReleaseSemaphore is Causing the Problem.
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 */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将
WaitForSingleObject(handles,INFINITE)
更改为WaitForSingleObject(handles[SemaphoreIndex],INFINITE)
。将
switch(WAIT_OBJECT_0)
更改为switch(dwWaitResult)
并向此开关添加错误处理。case StopperIndex:
应该是 caseStopperIndex + WAIT_OBJECT_0:
,对case SemaphoreIndex:
应用相同的更改,将编译器警告级别设置为最高,并修复问题它警告说。
正确的操作顺序是:
生产者:锁定临界区、添加到队列、释放临界区、释放信号量。
消费者:等待信号量,锁定临界区,从队列中获取,释放临界区。
您的代码似乎在等待生产者和消费者中的信号量,这将导致死锁。
Change
WaitForSingleObject(handles,INFINITE)
toWaitForSingleObject(handles[SemaphoreIndex],INFINITE)
.Change
switch(WAIT_OBJECT_0)
toswitch(dwWaitResult)
and add error handling to this switch.case StopperIndex:
should be caseStopperIndex + WAIT_OBJECT_0:
, apply same change tocase SemaphoreIndex:
Turn you compilers warning level to max, and fix what it warns about.
The correct order of operations is:
Producer: lock the critical section, add to queue, release critical section, release semaphore.
Consumer: wait for semaphore, lock critical section, fetch from queue, release critical section.
Your code appears to wait for the semaphore in both producer and consumer, which'll deadlock.