C++ 临界段队列

C++ 临界段队列,c++,winapi,critical-section,C++,Winapi,Critical Section,Windows关键部分中是否没有队列的概念 我在专用线程中有以下渲染循环: while (!viewer->finish) { EnterCriticalSection(&viewer->lock); viewer->renderer->begin(); viewer->root->render(viewer->renderer); viewer->renderer->end(); LeaveCriticalSec

Windows关键部分中是否没有队列的概念

我在专用线程中有以下渲染循环:

while (!viewer->finish)
{
  EnterCriticalSection(&viewer->lock);
  viewer->renderer->begin();
  viewer->root->render(viewer->renderer);
  viewer->renderer->end();
  LeaveCriticalSection(&viewer->lock);
}
主线程执行消息处理,当我处理鼠标事件时,我尝试进入相同的关键部分,但出于某种原因,在主线程最终进入关键部分之前,它会运行渲染线程一千次以上的迭代(大约10秒)。这是什么原因造成的?即使没有“队列”进入该部分,它是否应该更像50/50,而不是像我的例子中的99.9/0.1?两个线程的优先级均为0

添加此类队列的好方法是什么?像BDONOTRENDER这样的简单标志就足够了吗


编辑:在我的例子中,解决方案只是添加一个事件对象(一个布尔变量可能也会起作用),该对象在每次消息处理程序需要访问关键部分时设置,并在使用它后重置。如果设置了变量/事件,则渲染器不会进入节。这样,消息处理程序就不必等待一次以上的渲染迭代。

在旧版本的Windows中,保证以先到先得的方式获取关键部分。从WindowsServer2003SP1开始就不再是这样了

从:

从带有Service Pack 1(SP1)的Windows Server 2003开始,等待关键部分的线程不会以先到先得的方式获取关键部分。对于大多数代码,此更改显著提高了性能。但是,某些应用程序依赖于先进先出(FIFO)顺序,在当前版本的Windows上可能会表现不佳或根本没有表现(例如,使用关键部分作为速率限制器的应用程序)。为了确保代码继续正常工作,可能需要添加额外的同步级别。例如,假设您有一个生产者线程和一个消费者线程正在使用一个临界段对象来同步他们的工作。创建两个事件对象,每个线程使用一个事件对象来表示它已准备好让另一个线程继续。使用者线程将等待生产者在进入临界段之前发出事件信号,生产者线程将等待使用者线程在进入临界段之前发出事件信号。在每个线程离开临界段后,它会发出其事件的信号以释放另一个线程

Windows Server 2003和Windows XP:正在关键部分等待的线程被添加到等待队列中;它们被唤醒,通常按照添加到队列中的顺序获取关键部分。但是,如果线程以足够快的速度添加到此队列,则性能可能会下降,因为唤醒每个等待线程所需的时间太长

因此,不确定线程的执行顺序。如果你的头发很短

viewer->renderer->begin();
viewer->root->render(viewer->renderer);
viewer->renderer->end();

sequence设法重新获得关键部分,这可能会发生。

等待关键部分的线程不会以先到先得的方式获取关键部分()


大多数情况下,工作线程都拥有锁,因为它在释放锁后立即重新锁定。因此,当另一个线程空闲时,没有太多时间让它醒来并捕获锁。

您可以通过在渲染循环中使用call来尝试快速修复(经过一定次数的迭代),尽管我怀疑它是否是足够好的解决方案。

为什么
viewer->finish
不受并发访问的保护?它是否至少是易变的?while循环在解锁后立即锁定,这没有帮助。主线程和渲染线程的优先级是什么?因为查看器->完成仅由主线程修改。优先级都为零。我假设可能是这样的,但它是否至少应该在再次进入关键部分之前检查其他线程是否试图承担控制权?好的,这是我想要避免的,但谢谢。
如果所有调用线程具有相同的优先级,则在当前线程离开关键部分后将使用先进先出(FIFO)。
MSDN中的一行让我感到困惑。@riv:我在谷歌上搜索了这段引用,我看到的唯一一处引用是
Windows Mobile 6.5
。如果你的问题是关于Windows Mobile的,那么你应该这么说。是的,那是我的错误,我习惯于在visual studio中内置MSDN,现在我没有了它,我只是用谷歌搜索我需要的任何功能,并不总是注意到一个不寻常的平台。哎哟,我刚刚意识到我一直在关注Windows Mobile MSDN=(
viewer->renderer->begin();
viewer->root->render(viewer->renderer);
viewer->renderer->end();