Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中手动中断stdin.read(1)?_Python - Fatal编程技术网

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

如何在Python中手动中断stdin.read(1)?,python,Python,我尝试使用sys.stdin.write(chr(4))手动发送传输结束字符,但结果是io。不支持操作:不可写 我试图关闭stdin,但它不会立即终止阻塞读取(1)方法。它在我键入另一个键后触发异常 我尝试了选择器,但在调用selector.close()后,selector.select()需要额外的键。它本身需要一个事件循环,而这个循环将变得不可中断。如果在线程中运行该循环,则很难中断并保持原始进程运行。但是在子流程中运行这个循环很容易。因此,您可以中断子进程以中断阻塞stdin.read(

我尝试使用
sys.stdin.write(chr(4))
手动发送传输结束字符,但结果是
io。不支持操作:不可写

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


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

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

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()
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!\r\n", 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")