Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between subprocess.Popen preexec_fn and start_new_session in python

What is the difference between these two options to start a new process with subprocess.Popen for python3.2+ under Linux:

proc = subprocess.Popen(args, ..., preexec_fn=os.setsid)   # 1
proc = subprocess.Popen(args, ..., start_new_session=True) # 2

I need this as I need to set process group ID to have a possibility to kill at once this process and all of its children. This is then used in the case if the process run time exceeds certain threshold:

try:
    out, err = proc.communicate(timeout=time_max)
except subprocess.TimeoutExpired:
    os.killpg(os.getpgid(proc.pid), signal.SIGTERM) 

I tested my code with the both options (#1 & #2) and they both seem to work ok for me.

But I wonder what is the best option here - the one with preexec_fn or the one with start_new_session?

like image 833
Mikhail Geyer Avatar asked Feb 15 '17 18:02

Mikhail Geyer


People also ask

What is the difference between subprocess run and subprocess Popen?

The main difference is that subprocess. run() executes a command and waits for it to finish, while with subprocess. Popen you can continue doing your stuff while the process finishes and then just repeatedly call Popen. communicate() yourself to pass and receive data to your process.

What is subprocess Popen in Python?

The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.

What is the difference between subprocess call and run?

I can say that you use subprocess. call() when you want the program to wait for the process to complete before moving onto the next process. In the case of subprocess. run() , the program will attempt to run all the processes at once, inevitably causing the program to crash.

What is the difference between OS and subprocess in Python?

os. system is equivalent to Unix system command, while subprocess was a helper module created to provide many of the facilities provided by the Popen commands with an easier and controllable interface. Those were designed similar to the Unix Popen command.


1 Answers

According to the official Python Docs,

The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.

If you need to modify the environment for the child use the env parameter rather than doing it in a preexec_fn. The start_new_session parameter can take the place of a previously common use of preexec_fn to call os.setsid() in the child.

So I guess the answer to your question is that start_new_session was introduced to replace the common operation of using preexec_fn to set the session id through os.setsid(), which is not thread safe.

like image 137
Shaun Avatar answered Sep 28 '22 03:09

Shaun