Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: when to use pty.fork() versus os.fork()

I'm uncertain whether to use pty.fork() or os.fork() when spawning external background processes from my app. (Such as chess engines)

I want the spawned processes to die if the parent is killed, as with spawning apps in a terminal.

What are the ups and downs between the two forks?

like image 928
Thomas Ahle Avatar asked Dec 17 '09 14:12

Thomas Ahle


People also ask

Is the OS fork () in Python a system call?

The os. fork() function in Python provides the implementation of the system call fork(). The os. fork() when called from a program it creates a new process.

What does the OS fork () call do?

fork() method in Python is used to create a child process. This method work by calling the underlying OS function fork(). This method returns 0 in the child process and child's process id in the parent process.

What happens when the OS fork () function is executed?

Overview. This os. fork() method in Python provides the implementation of the fork() system, which creates a child or a forked process. Calling fork() results in the creation of an exact copy of the parent process.

What is Pty in Python?

Source code: Lib/pty.py. The pty module defines operations for handling the pseudo-terminal concept: starting another process and being able to write to and read from its controlling terminal programmatically. Pseudo-terminal handling is highly platform dependent.


3 Answers

The child process created with os.fork() inherits stdin/stdout/stderr from parent process, while the child created with pty.fork() is connected to new pseudo terminal. You need the later when you write a program like xterm: pty.fork() in parent process returns a descriptor to control terminal of child process, so you can visually represent data from it and translate user actions into terminal input sequences.

Update:

From pty(7) man page:

A process that expects to be connected to a terminal, can open the slave end of a pseudo-terminal and then be driven by a program that has opened the master end. Anything that is written on the master end is provided to the process on the slave end as though it was input typed on a terminal. For example, writing the interrupt character (usually control-C) to the master device would cause an interrupt signal (SIGINT) to be generated for the foreground process group that is connected to the slave. Conversely, anything that is written to the slave end of the pseudo-terminal can be read by the process that is connected to the master end.

like image 112
Denis Otkidach Avatar answered Oct 05 '22 23:10

Denis Otkidach


In the past I've always used the subprocess module for this. It provides a good api for communicating with subprocesses.

You can use call(*popenargs, **kwargs) for blocking execution of them, and I believe using the Popen class can handle async execution.

Check out the docs for more info.

As far as using os.fork vs pty.fork, both are highly platform dependent, and neither will work (or at least is tested) with windows. The pty module seems to be the more constrained of the two by reading the docs. The main difference being the pseudo terminal aspect. So if you aren't willing to architect your code in such a way as to be able to use the subprocess module, I'd probably go with os.fork instead of pty.fork.

like image 21
Bryan McLemore Avatar answered Oct 05 '22 23:10

Bryan McLemore


Pseudotermials are necessary for some applications that really expect a terminal. An interactive shell is one of these examples but there are many other. The pty.fork option is not there as another os.fork but as a specific API to use a pseudoterminal.

like image 28
pavlix Avatar answered Oct 05 '22 23:10

pavlix