想到一个控制子进程的 cpu 使用率的简单方法。
import platform
import time
from multiprocessing import Process, JoinableQueue
import psutil
from settings import CPU_FREQ, MIN_SLEEP_TIME_OF_SUBPROCESS, testLog
# CPU_FREQ = psutil.cpu_freq().max * pow(10, 9)
# MIN_SLEEP_TIME_OF_SUBPROCESS = 1 / CPU_FREQ
def subp(queue: JoinableQueue):
while 1:
if queue.empty():
_st = 0
else:
_st = queue.get()
queue.task_done()
time.sleep(_st)
if __name__ == '__main__':
sysv = platform.system().lower()
expect = 90
queue = JoinableQueue()
queue.put(MIN_SLEEP_TIME_OF_SUBPROCESS)
sp = Process(target=subp, args=(queue,))
sp.start()
spi = psutil.Process(sp.pid)
if sysv == "windows":
spi.nice(psutil.HIGH_PRIORITY_CLASS)
else:
spi.nice(28)
if sysv != "windows":
spi.ionice(psutil.IOPRIO_CLASS_RT, value=7)
testLog.info(f"pid: {spi.pid}, ppid: {spi.ppid()}")
time.sleep(5)
while 1:
scpu = spi.cpu_percent(MIN_SLEEP_TIME_OF_SUBPROCESS)
if scpu >= expect:
testLog.info(f"sub-process cpu: {scpu}")
if sysv != "windows":
testLog.info(f"sub-process cpu_num: {spi.cpu_num()}")
st = 1 / (((scpu - expect) / 100) * CPU_FREQ)
testLog.info(f"st: {st}")
else:
# st = MIN_SLEEP_TIME_OF_SUBPROCESS
st = 0
queue.put(st)
原理如下:
if 子进程的 cpu 占用率 > 预期:
1 / ((当前的占用率- 预期)/ 满载值 * cpu 频率。)
这个值就是子进程需要休眠的时间。
子进程只使用单核时,满载值就是 100 ,子进程再开孙子进程的情况还没考虑。
实测能达到预想效果。
各位还有其他的方案可以借鉴下吗?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.