实现非阻塞等待的最佳方法?

问题描述 投票:0回答:6

在Python中,如果我想让进程或线程永远运行,我通常可以使用空的while循环来做到这一点:

while 1: pass
然而,这会消耗不公平数量的 CPU 进程。添加一个短的 

sleep

 就可以了:

import time while 1: time.sleep(0.01)
有没有最好或更干净的方法来做到这一点?

python multithreading
6个回答
13
投票
考虑到相当奇怪的要求(一个在不使用太多 CPU 的情况下永远运行的过程),这是相当紧凑的:

import threading dummy_event = threading.Event() dummy_event.wait()

...但是,我担心我会屈服于解决你的 Y 而不是 X 的诱惑。

除此之外,如果您的平台不提供

threading

 模块,这将不起作用。如果您尝试替换 
dummy_threading
 模块,
dummy_event.wait()
 会立即返回。

更新:如果您只是为了子进程而保持父进程运行,则可以在 Popen 对象上使用

wait()方法,或在 join()
上使用 
Process
方法
物体。这两种方法都会无限期地阻塞,直到子进程结束。如果您正在使用其他一些子流程 API,那么必然会有等效的功能可用。如果没有,获取进程的 PID 并使用
os.waitpid()


3
投票
不要使用忙等待。根据您正在等待的内容,使用操作系统的阻塞等待功能之一,例如Unix 上为

select

,Windows 上为 
WaitForSingleObject
/
WaitForMultipleObjects


2
投票
如果您依赖此脚本执行定期维护,请使用 cron (UNIX) 或计划任务 (Windows)。

如果您希望等待子流程完成,请使用

os.waitpid

如果您希望等待文件系统活动,请使用

pyinotify


1
投票
睡眠时间很短有什么问题?对于现代计算机来说,1 毫秒接近永恒。如果您没有数千个这样的线程(听起来您没有),那么每次循环迭代休眠一、十、一万或一千万毫秒就没有什么问题。 CPU 甚至不会注意到这个小信号。


1
投票
有人可能会回答这个老问题,所以我将把它留在这里。 最佳方法是来自

apscheduler 模块的 BlockingScheduler,您还可以使用它定期安排作业(或类似 cron 或其他)

from datetime import datetime import os from apscheduler.schedulers.blocking import BlockingScheduler def tick(): print('Tick! The time is: %s' % datetime.now()) if __name__ == '__main__': scheduler = BlockingScheduler() scheduler.add_job(tick, 'interval', seconds=3) print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass
    

0
投票
这使用了类似于

https://stackoverflow.com/a/60631484/242042 中的答案的异步技术,它满足了即时要求,但它阻止了 stop()

 方法被调用。源自
Python asyncio:调用停止方法时事件循环似乎没有停止这就是我在 AHK 映射脚本中所做的事情

import asyncio from threading import Thread def stop_loop(): """ This can be called from another thread to schedule stopping the event loop """ loop.call_soon_threadsafe(loop.stop) thread = Thread(target=loop.run_forever) thread.start() thread.join()
    
© www.soinside.com 2019 - 2024. All rights reserved.