如何在 Python 中手动中断 stdin.read(1)?

  • 本文关键字:read stdin 中断 Python python
  • 更新时间 :
  • 英文 :

import sys
import threading
import tty
import termios

def loop():
fd = sys.stdin.fileno()
mode = termios.tcgetattr(fd)
tty.setraw(fd)
try:
while True:
sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, mode)

threading.Thread(target=loop).start()

我尝试使用sys.stdin.write(chr(4))手动发送传输结束字符,但它导致io.UnsupportedOperation: not writable.

我试图关闭 stdin,但它不会立即终止阻塞 read(1( 方法。在我键入另一个键后,它会触发异常。

我尝试了 seletors,但在我调用 selector.select(( 后需要额外的键selector.close().选择器本身需要一个事件循环,这个循环变得不可中断。

如果在线程中运行循环,则很难中断并保持原始进程运行。但是在子流程中运行此循环很容易。所以你可以中断子进程来中断阻塞 stdin.read(1(

import os
import sys
import tty
import termios
import time
import signal
from multiprocessing import Process
def loop():
# https://stackoverflow.com/questions/30134297/python-multiprocessing-stdin-input
# Subprocess stdin will be set to os.devnull. So we need to reopen it here.
# Use parent process stdin(fd=0) instead of subprocess stdin(fd=7)
sys.stdin = open(0)  #
fd = sys.stdin.fileno()
mode = termios.tcgetattr(fd)
tty.setraw(fd)
try:
while True:
ch = sys.stdin.read(1)
if ord(ch) == 3:
break
except KeyboardInterrupt:
print("interrupted!rn", end="")
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, mode)

if __name__ == '__main__':
p = Process(target=loop)
p.start()
time.sleep(1)
os.kill(p.pid, signal.SIGINT)
p.join()
print("done")

最新更新