【问题标题】:Threads are slow when audio is off音频关闭时线程很慢
【发布时间】:2012-12-27 06:49:59
【问题描述】:

我有 2 个项目。一种是由没有 MFC 风格的 C++ Builder 构建的。另一个是VC++ MFC 11。

当我创建一个线程并创建一个循环时——假设这个循环向进度条位置添加一个——使用Sleep(10) 从 1 到 100,它当然适用于 C++ Builder 和 C++ MFC。

现在,Sleep(10) 等待 10 毫秒。好的。但问题仅在于我有打开的媒体播放器、Winamp 或其他任何能产生“声音”的东西。如果我关闭所有媒体播放器、winamp 和其他声音程序,我的线程会慢于 10 毫秒。

它需要像50-100 ms / each。如果我打开任何音乐,它会按预期正常运行。

我不知道为什么会这样。我一开始以为我在 MFC App 里面犯了一个错误,但是为什么 C++ Builder 也变慢了?

是的,我确信这与声音有关,因为我什至重新格式化了我的窗口,禁用了所有内容。最后我发现了那个声音问题。

我的代码需要什么吗?

更新

现在,我按照代码,发现我在这样的区域使用Sleep(1)要等待1毫秒。原因是,我从左向右移动一个对象。如果我取消这个睡眠,那么移动就不会出现,因为它非常快。所以,我应该使用Sleep(1)。使用Sleep(1),如果音频on 则可以正常工作。如果音频关闭则非常慢。

for (int i = 0; i <= 500; i++) {
   theDialog->staticText->SetWindowsPosition(NULL, i, 20, 0, 0);
   Sleep(1);
}

因此,非常感谢有关此的建议。我该怎么办?

我知道这是错误的方法。我应该使用其他适当且有效的东西。但究竟是什么?哪个函数或类可以帮助我将静态文本从一个位置顺利移动到另一个位置?

另外,更改线程优先级也没有帮助。

更新 2

更新 1 是另一个问题 :)

【问题讨论】:

  • 进程的优先级相同。第二个有趣的事情是,如果我打开媒体播放器(但不播放音乐),我的线程程序以 2% 的 CPU 运行并且线程工作。如果我关闭媒体播放器,立即减速并占用 0% 的 CPU。
  • 这可能是由于处理器限制了 cpu 的频率。
  • 一切都是为了省电。 :-)
  • 我想知道如果我使用SetSystemPowerState(); 这会做任何事情吗? (我现在没有 VS IDE)
  • @xangr 啊,好的。我不知道人们会这么说,但这是有道理的。

标签: c++ audio mfc


【解决方案1】:

睡眠 (10),将(我们知道)等待大约 10 毫秒。如果此时有更高优先级的线程需要运行,线程唤醒可能会延迟。多媒体线程可能以实时或高优先级运行,因此当您播放声音时,您的线程唤醒会延迟。

请参阅 Microsoft Windows 编程应用程序(第 4 版)第 7 章睡眠部分中的 Jeffrey Richters 评论:

系统使线程在大约 指定的毫秒数。没错——如果你告诉系统 你想睡 100 毫秒,你会睡大约 这么长,但可能还要几秒钟或几分钟。请记住 Windows 不是实时操作系统。你的线程可能会 在正确的时间醒来,但它是否真的取决于其他是什么 在系统中进行。

同样根据 MSDN Multimedia Class Scheduler Service (Windows)

MMCSS 确保对时间敏感的处理接收对 CPU 资源的优先访问。

根据上述文档,您还可以通过注册表项控制保证低优先级任务的 CPU 资源百分比

【讨论】:

    【解决方案2】:

    Sleep(10) 等待至少 10 毫秒。您必须编写代码来检查您实际等待了多长时间,如果超过 10 毫秒,请在代码中妥善处理。 Windows 不是实时操作系统。

    【讨论】:

    • 我相信他知道这一点。问题是什么对量子的大小有如此大的影响,或者它是否只是随机的机会。此外,根据问题“明智地处理”是不可能的(例如音频或视频重播)。
    • @Voo 是对的。我知道这一点。我会在安装 IDE 后尝试使用SetSystemPowerState() 函数来解决这个问题。
    • @Voo:他正在更新进度条位置。明智地处理它几乎是微不足道的。
    • @xangr:当您可以在自己的代码中轻松处理此问题时,为什么还要对性能产生严重、剧烈的系统范围负面影响?
    • 根据第二个答案,你说对了一半(我认为一半是正确的词)。 (关于实时操作系统)
    【解决方案3】:

    Sleep() 计时的最小分辨率在系统范围内设置为 timeBeginPeriod()timeEndPeriod()。例如传递 timeBeginPeriod(1) 将最小分辨率设置为 1 毫秒。可能是音频程序将分辨率设置为 1 毫秒,并在完成后将其恢复为大于 10 毫秒。我遇到了一个使用 Sleep(1) 的程序的问题,该程序仅在 XE2 IDE 运行时才能正常工作,否则会休眠 12 毫秒。我通过在程序开头直接设置timeBeginPeriod(1)解决了这个问题。

    见:http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624%28v=vs.85%29.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-07
      • 2017-10-05
      • 2011-03-13
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多