对信号量做了太多帖子

时间:2011-03-07 09:36:53

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

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

我已经占用了一个队列而且我已经限制了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 个答案:

答案 0 :(得分:2)

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

switch(WAIT_OBJECT_0)更改为switch(dwWaitResult),并为此切换添加错误处理。

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

将编译器警告级别调到最大,并修复它所警告的内容。

正确的操作顺序是:

制作人:锁定关键部分,添加到队列,释放关键部分,释放信号量。

消费者:等待信号量,锁定关键部分,从队列中获取,释放关键部分。

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