Python: 何时使用 pty.fork() 而非 os.fork()

14 投票
3 回答
6446 浏览
提问于 2025-04-15 17:08

我不太确定在我的应用程序中启动外部后台进程时,是使用 pty.fork() 还是 os.fork()。比如说像国际象棋引擎这样的程序。

我希望这些启动的进程在父进程被杀掉时也能一起结束,就像在终端中启动应用程序一样。

这两种方法各有什么优缺点呢?

3 个回答

2

伪终端是一些应用程序所必需的,这些应用程序确实需要一个终端。交互式命令行就是一个这样的例子,但还有很多其他的应用。pty.fork这个选项并不是像os.fork那样的普通功能,而是一个专门用来使用伪终端的接口。

4

过去我一直使用 subprocess 模块来处理这个问题。这个模块提供了一个很好的接口,可以与子进程进行通信。

你可以使用 call(*popenargs, **kwargs) 来阻塞执行子进程,也就是说在这个子进程完成之前,程序会停下来等它。还有 Popen 类可以用来处理异步执行,也就是可以同时运行多个进程。

想了解更多信息,可以查看这个 文档

关于 os.forkpty.fork 的使用,这两个方法都很依赖于操作系统,而且在 Windows 上都不太适用(或者说没有经过测试)。从文档来看,pty 模块似乎限制更多,主要是因为它涉及到伪终端的功能。所以如果你不想把代码设计得特别复杂以便使用 subprocess 模块,我建议你使用 os.fork 而不是 pty.fork

11

通过 os.fork() 创建的子进程会继承父进程的标准输入、输出和错误输出,而通过 pty.fork() 创建的子进程则会连接到一个新的伪终端。你在写像 xterm 这样的程序时需要使用后者:在父进程中调用 pty.fork() 会返回一个描述符,用来控制子进程的终端,这样你就可以把从子进程获取的数据可视化,并将用户的操作转换成终端输入的指令。

更新:

来自 pty(7) 手册页:

一个期望连接到终端的进程,可以打开伪终端的从端,然后由一个打开了主端的程序来驱动。写入主端的任何内容都会被当作在终端上输入的内容提供给从端的进程。例如,向主设备写入中断字符(通常是控制键 C)会导致为连接到从端的前台进程组生成一个中断信号(SIGINT)。反过来,写入伪终端的从端的任何内容都可以被连接到主端的进程读取。

撰写回答