使线程成为将自动终止的守护线程
启动标准输入读取线程daemon=True。当主线程终止时,它将自动终止。您不需要显式地对 stdin 执行任何操作。 (您也没有机会在标准输入读取线程中进行清理。)例如:
stdinTh = threading.Thread(target=stdinLoop, name="stdinTh")
stdinTh.daemon = True
stdinTh.start()
如果您不能或不想使用守护线程
sys.stdin.readline()
最终归结为阻塞read()系统调用。
read()
on stdin
不返回时stdin
关闭了。我不确定你为什么期望它。这不是 Python 特有的行为。至少在我的 Linux/glibc 系统上,C 语言中也会发生同样的情况。
你可以突破阻碍read()
通过发送信号(例如SIGUSR1
) 到被阻塞的线程。在C中,你可以使用pthread_kill()为了那个原因。 Python 没有提供一种简单的方法来做到这一点,这是有充分理由的;但如果你坚持的话,你可以做它与ctypes.
但更清洁/更安全的方法是使用select.select从中读取either stdin or线程间通信管道,以先可用者为准:
import os, select, sys, threading, time
def printer_loop(quit_pipe):
while True:
sys.stdout.write("Say something: ")
sys.stdout.flush()
(readable, _, _) = select.select([sys.stdin, quit_pipe], [], [])
if quit_pipe in readable:
print("Our time is up!")
break
# This is not exactly right, because `sys.stdin` could become
# ready for reading before there's a newline on there, so
# `readline` could still block. Ideally you would do some
# custom buffering here.
line = sys.stdin.readline()
print("You said: '%s' - well said!" % line.strip())
def main():
print("Starting thread...")
(pipe_read, pipe_write) = os.pipe()
thread = threading.Thread(target=printer_loop, args=(pipe_read,))
thread.start()
time.sleep(5)
print("Interrupting thread...")
os.write(pipe_write, b'.')
print("Joining thread...")
thread.join()
print("All done!...")
if __name__ == '__main__':
main()
这不能移植到 Windows,您不能select()
on sys.stdin
.