Python create child process module subprocess details

  • 2020-05-07 19:57:33
  • OfStack

Recently, our boss asked me to write a guardian program to guard the server process. If the server fails, the guardian can restart the application immediately. After surfing Google for 1, I found that Python has several modules that can create processes. Finally, I chose to use the subprocess module, because there is a paragraph in the Python manual that says:

This module to replace other, older modules and functions, such as: os.system, os spawn*, os.popen*, popen2.*, commands.*

subprocess is used to replace some old modules and functions, such as os.system, os.spawn *, os.popen *, popen2.*, commands.*. As you can see, subprocess is the recommended module.

Here is a very simple example: create a new process, execute app1.exe, pass in the corresponding parameters, and print out the return value of the process:


import subprocess returnCode = subprocess.call('app1.exe -a -b -c -d')
print 'returncode:', returnCode #----- The results of --------
#Python is powerful
#app1.exe
#-a
#-b
#-c
#-d
returncode: 0

app1.exe is a very simple console program that only prints out the parameters passed in. The code is as follows:

#include <iostream>
using namespace std; int main(int argc, const char *argv[])
{
    cout << "Python is powerful" << endl;
    for (int i = 0; i < argc; i++)
    {
        cout << argv[i] << endl;
    }     return 0;
}

Without further elaboration, the subprocess module is now described in detail. There is only one class defined in the subprocess module: Popen. You can use Popen to create and interact with processes in complex ways. Its constructor function is as follows:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

The parameter args can be a string or sequence type (e.g., list, tuple) that specifies the executable file of the process and its parameters. If it is a sequence type, the first element is usually the path to the executable. We can also explicitly specify the path of the executable using the executeable parameter. On the windows operating system, Popen creates child processes by calling CreateProcess(),CreateProcess receives one string argument, and if args is a sequence type, the system converts the sequence type to a string through the list2cmdline() function.
Parameter bufsize: specifies the buffer. I still do not know the specific meaning of this parameter, hope each big cow points out.
The parameter executable is used to specify an executable program. In general, we set the program to run by args parameter. If the parameter shell is set to True, executable specifies the shell used by the program. On the windows platform, the default shell is specified by the COMSPEC environment variable.
The parameters stdin, stdout, stderr represent the standard input, output, and error handles of the program, respectively. They can be PIPE, file descriptors or file objects, or they can be set to None to represent inheritance from the parent process.
The preexec_fn parameter is valid only on the Unix platform and specifies an executable object (callable object) that will be called before the child process runs.
Parameter Close_sfs: on the windows platform, if close_fds is set to True, the newly created child process will not inherit the input, output, and error pipes of the parent process. We cannot set close_fds to True and redirect the standard inputs, outputs, and errors of the child process (stdin, stdout, stderr).
If the parameter shell is set to true, the program will be executed through shell.
Parameter cwd is used to set the current directory of the child process.
The parameter env is a dictionary type that specifies the environment variable for the child process. If env = None, the child process's environment variables are inherited from the parent process.
Parameter Universal_newlines: the newline character of the text is not the same under different operating systems. For example, '/r/n' for windows, '/n' for Linux. If this parameter is set to True, Python series 1 treats these line breaks as '/n'.
The parameters startupinfo and createionflags are only valid under windows. They are passed to the underlying CreateProcess() function, which sets some properties of the child process, such as the appearance of the main window, the priority of the process, and so on.

subprocess.PIPE
When
creates Popen objects, subprocess.PIPE can initialize stdin, stdout, or stderr parameters. Represents the standard flow that communicates with the child process.

subprocess.STDOUT
When
creates the Popen object, it is used to initialize the stderr parameter, which means to output the error through the standard output stream.


Popen method:
Popen.poll()
is used to check if the child process has ended. Sets and returns the returncode property.
Popen.wait()
waits for the child process to finish. Sets and returns the returncode property.
Popen.communicate(input=None)
interacts with child processes. Send data to stdin or read data from stdout and stderr. The optional parameter input specifies the parameters to be sent to the child process. Communicate() returns 1 tuple :(stdoutdata, stderrdata). Note: if you want to send data to a process through its stdin, the parameter stdin must be set to PIPE when the Popen object is created. Similarly, if you want to get data from stdout and stderr, you must set stdout and stderr to PIPE.
Popen.send_signal(signal)
sends a signal to the child process.
Popen.terminate()
stops the (stop) child process. On the windows platform, the method calls Windows API TerminateProcess () to end the child process.
Popen.kill()
kills child processes.
Popen.stdin
if the Popen object is created, the parameter stdin is set to PIPE, Popen.stdin will return a file object for the child process to send instructions. Otherwise return None.
Popen.stdout
if the Popen object is created, the parameter stdout is set to PIPE, Popen.stdout will return a file object for the child process to send instructions. Otherwise return None.
Popen.stderr
if the Popen object is created, the parameter stdout is set to PIPE, Popen.stdout will return a file object for the child process to send instructions. Otherwise return None.
Popen.pid
gets the process ID of the child process.
Popen.returncode
gets the return value of the process. If the process has not finished, return None.
  the following is a very simple example of how the supprocess module interacts with a console application.

 


 import subprocess p = subprocess.Popen("app2.exe", stdin = subprocess.PIPE, /
    stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = False) p.stdin.write('3/n')
p.stdin.write('4/n')
print p.stdout.read() #---- The results of ----
input x:
input y:
3 + 4 = 7
 

  app2.exe is also a very simple console program that receives two values from the interface, performs the addition, and prints the results to the console. The code is as follows:
 


 #include <iostream>
using namespace std; int main(int argc, const char *artv[])
{
    int x, y;
    cout << "input x: " << endl;
    cin >> x;
    cout << "input y: " << endl;
    cin >> y;
    cout << x << " + " << y << " = " << x + y << endl;     return 0;
}
 

The   supprocess module provides some functions that we can use to create processes.
subprocess.call(*popenargs, **kwargs)
runs the command. This function waits 1 until the child process runs, and returns returncode of the process. The example at the beginning of article 1 illustrates the call function. If the child process does not need to interact, it can be created using this function.
subprocess.check_call(*popenargs, **kwargs)
is the same as subprocess.call (*popenargs, **kwargs) except that if the child process returns returncode which is not 0, CalledProcessError exception will be triggered. In the exception object, the returncode information for the process is included.
 
So much for the subprocess module. In the Python manual, there are also examples of how to use subprocess to replace old modules, old functions. Those of you who are interested can read 1.


Related articles: