较快的线程会阻塞较慢的线程

A faster thread blocks slower thread

本文关键字:线程      更新时间:2023-10-16

我正在开发点云查看器,我的设计基于两个线程

  • 第一个线程更新点云数据(大约 10 fps)
  • 第二个线程是D3D渲染器,用于渲染设置为屏幕的点(约90 fps)

所以我的代码看起来像这样:

std::shared_ptr<PointCloud> pointcloud;
CRITICAL_SECTION updateLock;
void FirstThreadProc()
{
      while(true)
      {
       /* some algorithm processes point cloud, takes time */
            EnterCriticalSection(&updateLock);
            pointcloud->Update(data,length,...); //also takes time to copy and process
            LeaveCriticalSection(&updateLock);
      }
}
/*...*/  
std::shared_ptr<D3DRenderer> renderer;
void SecondThreadProc()
{
    MSG msg = { 0 };
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            EnterCriticalSection(&updateLock);
            renderer->Render(pointcloud);
            LeaveCriticalSection(&updateLock);
        }
    } 
}
我以为第二个线程比第一个线程

快得多,所以当第一个线程进入关键部分时,第二个线程被阻塞,所以渲染器窗口应该现在或那时冻结。 但我现在观察到的是渲染器窗口运行非常流畅,相机旋转或放大/缩小, 都很好,但是第一个线程非常不稳定,它的fps从10 fps到1 fps不等。

我正在考虑两个点云缓冲区,然后第一个线程在关键部分之外更新第二个缓冲区,然后在关键部分内交换两个缓冲区。会起作用吗?

如前所述,CRITICAL_SECTION不提供先进先出 (FIFO) 排序。 由于第二个线程比第一个线程快得多,并且它的整个循环是关键部分,因此它将在离开它后立即进入关键部分。这可能总是在关键部分,并将第一个排除在外。

我的解决方案是将第二个线程的更多工作放在关键部分之外,然后它工作正常。