在 C++ 中退出循环尽可能接近 30 毫秒的最佳方法是什么?轮询增强:microsec_clock ?轮询 QTime ?还有别的事吗?

就像是:

A = now;
for (blah; blah; blah) {
    Blah();
    if (now - A > 30000)
         break;
}

它应该可以在 Linux、OS X 和 Windows 上运行。

循环中的计算用于更新模拟。每 30 毫秒,我想更新一次视口。

有帮助吗?

解决方案

在这个环节相当多的代码片段例如你想要做什么:

http://www.cplusplus.com/reference/clibrary/ctime/时钟/

从它们的例子改编:

void runwait ( int seconds )
{
   clock_t endwait;
   endwait = clock () + seconds * CLOCKS_PER_SEC ;
   while (clock() < endwait)
   {
      /* Do stuff while waiting */
   }
}

其他提示

  

在循环中的计算是针对   更新模拟。每30毫秒,我   要更新的视口。

让您使用线程的考虑?你描述的似乎是为什么你应该使用,而不是定时器线程很好的例子。

在主进程线程保持取UI的护理,并且具有设置QTimer至30ms来更新它。它可以锁定一个 QMutex 来访问数据,执行更新,并释放互斥。

在第二螺纹(参见的QThread )做模拟。对于每个周期,将锁定QMutex,莫非计算并释放互斥当数据是在稳定的状态(适于UI更新)。

随着多核心处理器增加的趋势,你应该考虑越来越多地使用线程比使用计时器。应用程序从新的处理器的增加的功率(多芯)自动获益。

虽然这不会回答这个问题,可能会给再来看一看解决方案。怎么样将在不同的线程模拟代码和用户界面?如果您使用Qt,定期更新可使用计时器甚至的QThread :: msleep(实现)。您可以调整螺纹曼德尔布罗例如,以满足您的需要。

如果您需要等到一定时间之后做的工作,然后的 docflabby的回答是斑点上。不过,如果你只需要等待,无所作为,直到指定的时间已经过去,那么你应该使用的 usleep()

简短的回答是:你不能在一般情况下,但你可以的,如果你在正确的OS或右边的硬件上运行。

您可以关闭到30毫秒的所有操作系统的使用在Intel系统上装配通话和其他架构别的东西。我会来挖了参考和编辑的答案,包括代码,当我找到它。

问题是时间切片算法,以及如何接近你的时间片的结尾,你是在一个多任务操作系统。

在一些实时操作系统的,有一个在系统库,你可以做一个系统调用,但我不知道电话是什么。

编辑:LOL!有人已经张贴在SO一个类似的片段:定时器功能,提供时间在用C纳米秒++

VonC得到了与CPU计时器汇编代码的注释在它

根据你的问题,你想每 30 毫秒更新一次视口。我曾经编写过一个类似的应用程序,每 500 毫秒探测一次硬件以查找类似的内容。虽然这并不能直接回答你的问题,但我有以下后续行动:

  • 您确定用于更新视口的 Blah() 在每个实例中都可以在 30 毫秒内执行吗?
  • 似乎更像是通过计时器回调运行 Blah() 会更好。
  • 很难找到一个能够以 30 毫秒的间隔推送来在图形框架中进行更新的库计时器对象。在 Windows XP 上,我发现标准 Win32 API 计时器在计时器间隔到期时推送窗口消息,即使在 2GHz P4 上,也无法以超过 300 毫秒的间隔进行更新,无论我将计时器间隔设置为多低。计时器。虽然 Win32 API 中有可用的高性能计时器,但它们有许多限制,即您不能像上面引用的那样在循环中执行任何 IPC(例如更新 UI 小部件)。
  • 基本上,结果是您必须非常仔细地计划如何进行更新。您可能需要使用线程,并看看您要如何更新视口。

只是一些需要考虑的事情。当我从事我的项目时,他们让我感到惊讶。如果您已经考虑清楚这些事情,请忽略我的回答:0)。

您可以考虑只更新视口,而每N个模拟步骤不是每K毫秒。如果是这样(说)一个严重的商业应用程序,那么你可能会想要去的多线程路线别处建议,但如果(说)这是为个人或有限的观众使用,哪些是你真正感兴趣是不管它是细节你模拟,然后每-N-步骤简单,便于携带,很可能是不够好是越来越上。

请参阅QueryPerformanceCounter和QueryPerformanceFrequency的

如果您使用的是Qt,这里有一个简单的方法来做到这一点:

QTimer* t = new QTimer( parent ) ;
t->setInterval( 30 ) ; // in msec
t->setSingleShot( false ) ;
connect( t, SIGNAL( timeout() ), viewPort, SLOT( redraw() ) ) ;

您需要指定viewPortredraw()。然后用t->start()启动定时器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top