对信号量进行了太多帖子

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) 处被阻塞。它们永远不会超出此范围

以上是关于对信号量进行了太多帖子的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程线程锁

通过将命令行工具包装在带有 gnu 信号量的 bash 脚本中来并行化命令行工具

关于用MATLAB设计对信号进行频谱分析和滤波处理的程序

在 MySQL 中进行排序时查询花费了太多时间

用MATLAB设计对信号进行频谱分析和滤波处理的程序

采用MATLAB对正弦信号,语音信号进行生成采样和恢复,利用MATLAB工具箱对混杂噪声的音频信号进行滤波