【问题标题】: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 */

【问题讨论】:

    标签: c++ multithreading visual-c++


    【解决方案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) 处被阻塞。它们永远不会超出此范围
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    相关资源
    最近更新 更多