有意地只限制一个线程的CPU使用
Throttle CPU usage of only one thread intentionally
关于SO还有其他几个类似的问题,但没有一个有令人满意的/相关的答案。
我有一个单线程c++程序,它基本上是这样做的:
while(true) {
//do things which are cpu bound
}
问题是,当我运行这个程序时,它通常是我的整个计算机上唯一一个正在进行活动工作的进程。
由于没有其他事情可调度,操作系统自然会大量调度这个程序,我的CPU使用率飙升到屋顶,我不想要。当然,我的风扇也开始嗡嗡作响,这特别烦人。
我解决这个问题的方法是在循环中添加sleep(100)
(这对我来说是正确的),但是当它工作时,它惹恼了我,它不是技术上正确的解决方案。
这是因为如果我想睡眠一个非常准确的时间,我有很多其他进程在我的计算机上运行,这将不是一个很好的解决方案,因为sleep
是不准确的,它也不允许其他进程使用CPU,而我的程序仍在调度-但这不是我真正的问题。
在不使用sleep
的情况下减少CPU使用的正确解决方案是什么,假设这是唯一正在积极运行的程序?
这里有三种情况需要考虑。
轮询循环
对于轮询循环,"正确"的解决方案更像是:
while(true) {
wait_for_something();
//do things which are cpu bound
}
问题是决定你应该等待什么(时间,按键,垂直同步信号,收到的数据包,....?);然后试着去找一些你真正需要的东西。
CPU绑定终端条件
对于这种情况,"正确"的解决方案更像是:
do {
//do things which are cpu bound
} while (running);
在这种情况下,你可以(应该)将线程的优先级设置为"非常低优先级",这样它就不会干扰其他线程。当只有低优先级线程运行时,操作系统可以决定是否(或不)降低CPU功率/速度;但这不是你的决定(这是操作系统的决定,希望有一些用户/管理员的电源管理控制)。
CPU Bound Without Terminal Condition
这种情况极其罕见(罕见到我想不出一个合理的场景,我甚至不确定它是否存在于实践中)。大多数情况下,如果你认为你的情况是"CPU绑定没有终端条件",你可能错了,它可能是其他情况之一。
如果它实际上是"CPU绑定没有终端条件",那么它基本上就像"CPU绑定与终端条件"一样,除了没有条件(你仍然想要一个低优先级的线程,当只有低优先级的线程运行时电源管理仍然不是你的决定)。
这在程序内部是比较困难的。可以说,大多数有效的方法(至少是我所知道的)都是从外部强加的。
在Linux上,一种可能是cpulimit,它监视CPU使用情况,并在必要时周期性地暂停您的程序,以将其CPU使用降低到您指定的水平。
Linux确实有setrlimit和cgroups之类的东西来控制进程的资源使用情况,但是这些都不适用于您指定的场景(例如,限制CPU使用,即使系统处于空闲状态)。传统上,您能够设置的限制是进程的总 CPU使用率,而不是使用率率,所以像setrlimit
和rctl
这样的东西有点类似,但不能提供您想要的东西。
如果你使用的是Windows,你可以通过Windows Job Object来实现。您创建一个作业对象,然后使用JOBOBJECT_CPU_RATE_CONTROL_INFORMATION使用SetInformationJobObject在该作业对象上设置限制。
在处理数字运算问题时,我经常遇到使用perl脚本的类似情况。在运行这些脚本时,我将机器置于省电模式(通过设置最大cpu阈值限制)。帮助。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- 在另一个线程中调用luaL_error会引发qWarning
- C++一个线程如何正确通信其任务已完成?
- 最佳做法是从另一个线程访问 qml 中的Q_PROPERTY
- C++线程:如何在一个线程仍在运行时阻止另一个线程执行 (Win32)
- 如何制作一个只能在一个线程上同时执行的函数?
- 结束另一个线程中使用的对象的生存期
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 一个线程等待多个线程事件
- 从不同进程中的另一个线程挂起/恢复线程或进程
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 计时器是否从另一个线程启动?
- 互斥,Windows 10,c ++,在一个线程上获取,在另一个线程上发布
- Qt 在另一个线程中无限循环
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 从另一个线程发出信号是否安全?
- AMQP-CPP,libev >停止ev_loop来自另一个线程