向信号量发送了太多帖子

发布于 2024-10-20 15:46:27 字数 2114 浏览 1 评论 0原文

您好,我们开发了一个示例代码来实现多个生产者和单个消费者问题。

我已经采取了一个队列,并将其大小限制为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2024-10-27 15:46:27

WaitForSingleObject(handles,INFINITE) 更改为 WaitForSingleObject(handles[SemaphoreIndex],INFINITE)

switch(WAIT_OBJECT_0) 更改为 switch(dwWaitResult) 并向此开关添加错误处理。

case StopperIndex: 应该是 case StopperIndex + WAIT_OBJECT_0:,对 case SemaphoreIndex: 应用相同的更改,

将编译器警告级别设置为最高,并修复问题它警告说。

正确的操作顺序是:

生产者:锁定临界区、添加到队列、释放临界区、释放信号量。

消费者:等待信号量,锁定临界区,从队列中获取,释放临界区。

您的代码似乎在等待生产者和消费者中的信号量,这将导致死锁。

Change WaitForSingleObject(handles,INFINITE) to WaitForSingleObject(handles[SemaphoreIndex],INFINITE).

Change switch(WAIT_OBJECT_0) to switch(dwWaitResult) and add error handling to this switch.

case StopperIndex: should be case StopperIndex + WAIT_OBJECT_0:, apply same change to case 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文