Last Updated on September 12, 2022
You can query the status of a multiprocessing.Process via attributes such as name, daemon and pid.
In this tutorial you will discover how to query the status of a process in Python.
Let’s get started.
Need to Query Process Attributes
A process is a running instance of a computer program.
Every Python program is executed in a Process, which is a new instance of the Python interpreter. This process has the name MainProcess and has one thread used to execute the program instructions called the MainThread. Both processes and threads are created and managed by the underlying operating system.
Sometimes we may need to create new child processes in our program in order to execute code concurrently.
Python provides the ability to create and manage new processes via the multiprocessing.Process class.
You can learn more about multiprocessing in the tutorial:
An instance of the multiprocessing.Process class provides a handle of a Python process. As such, it provides attributes that we can use to query properties and the status of the underlying process.
How can we query attributes of a multiprocessing.Process instance?
Run loops using all CPUs, download your FREE book to learn how.
How to Query Process Attributes
The multiprocessing.Process class provides instance attributes that can be used to query the status of the process.
This includes queries such as the process name and whether the process is currently alive.
The following provides a list of multiprocessing.Process attributes that we can query:
- name: Get or set the name of the process.
- daemon: Get or set whether the process is a daemon process or not.
- pid: Get the process identifier, once it is started.
- exitcode: Get the exit code for the process, once it is terminated.
- authkey: Get the authentication key for a process.
- sentinel: Get the sentinel object for a process.
- is_alive(): Check if the process is currently running.
Only the “name” and “daemon” attributes can be both accessed (retrieved) and set (assigned) after the multiprocessing.Process has been instantiated. The “daemon” attribute cannot be changed after the start() function has been called to run the thread.
The “pid” attribute is read-only and returns a positive integer value after the process has started. The “exitcode” attribute is read-only and returns an integer value after the process has terminated.
The “is_alive()” function (not an attribute) returns a boolean value as to whether the read is currently executing its run() function, e.g. running, or not.
Now that we are familiar with how to query the status of a process, let’s look at some examples.
Example of Querying Process Name
Each process has a name.
The parent process has the name “MainProcess“.
Child processes are named automatically in a somewhat unique manner within each process with the form “Process-%d” where %d is the integer indicating the process number created by the parent process, e.g. Process-1 for the first process created.
We can access the name of a process via the multiprocessing.Process.name attribute, for example:
1 2 3 |
... # report the process name print(process.name) |
The example below creates an instance of the multiprocessing.Process class and reports the default name of the process.
1 2 3 4 5 6 7 8 9 |
# SuperFastPython.com # example of accessing the child process name from multiprocessing import Process # entry point if __name__ == '__main__': # create the process process = Process() # report the process name print(process.name) |
Running the example creates a child process and reports the default name assigned to the process.
1 |
Process-1 |
Free Python Multiprocessing Course
Download your FREE multiprocessing PDF cheat sheet and get BONUS access to my free 7-day crash course on the multiprocessing API.
Discover how to use the Python multiprocessing module including how to create and start child processes and how to use a mutex locks and semaphores.
Example of Querying Process Daemon
A process may be a daemon.
Daemon process is the name given to the background process. By default, processes are non-daemon processes because they inherit the daemon value from the parent process, which is set False for the MainProcess.
A Python parent process will only exit when all non-daemon processes have finished exiting. For example, the MainProcess is a non-daemon process. This means that the daemon process can run in the background and do not have to finish or be explicitly excited for the program to end.
We can determine if a process is a daemon process via the multiprocessing.Process.daemon attribute.
1 2 3 |
... # report the daemon attribute print(process.daemon) |
The example creates an instance of the multiprocessing.Process class and reports whether the process is a daemon or not.
1 2 3 4 5 6 7 8 9 |
# SuperFastPython.com # example of assessing whether a process is a daemon from multiprocessing import Process # entry point if __name__ == '__main__': # create the process process = Process() # report the daemon attribute print(process.daemon) |
Running the example reports that the process is not a daemon process, the default for new child processes.
1 |
False |
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Example of Querying Process PID
Each process has a unique process identifier, called the PID, assigned by the operating system.
Python processes are real native processes, meaning that each process we create is actually created and managed by the underlying operating system. As such, the operating system will assign a unique integer to each thread that is created on the system (across processes).
The process identifier can be accessed via the multiprocessing.Process.pid property and is assigned after the process has been started.
1 2 3 |
... # report the pid print(process.pid) |
The example below creates an instance of a multiprocessing.Process and reports the assigned PID.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# SuperFastPython.com # example of reporting the native process identifier from multiprocessing import Process # entry point if __name__ == '__main__': # create the process process = Process() # report the process identifier print(process.pid) # start the process process.start() # report the process identifier print(process.pid) |
Running the example first creates the process and confirms that it does not have a native PID before it was started.
The process is then started and the assigned PID is reported.
Note, your PID will differ as the process will have a different identifier each time the code is run.
1 2 |
None 16302 |
Example of Querying Process Alive
A process instance can be alive or dead.
An alive process means that the run() method of the multiprocessing.Process instance is currently executing.
This means that before the start() method is called and after the run() method has completed, the process will not be alive.
We can check if a process is alive via the multiprocessing.Process.is_alive() method.
1 2 3 |
... # report the process is alive print(process.is_alive()) |
The example below creates a multiprocessing.Process instance then checks whether it is alive.
1 2 3 4 5 6 7 8 9 |
# SuperFastPython.com # example of assessing whether a process is alive from multiprocessing import Process # entry point if __name__ == '__main__': # create the process process = Process() # report the process is alive print(process.is_alive()) |
Running the example creates a new multiprocessing.Process instance then reports that the process is not alive.
1 |
False |
We can update the example so that the process sleeps for a moment and then reports the alive status of the process while it is running.
This can be achieved by setting the “target” argument to the multiprocessing.Process to execute a custom function that sleeps for one second.
First, we can define the function.
1 2 3 |
# function to execute in a new process def task(): sleep(1) |
Then we can create a new process instance and configure it to execute our function in a new thread.
1 2 3 |
... # create the process process = Process(target=task) |
We can then start the process by calling the start() function and report the alive status of the process while it is running.
1 2 3 4 5 |
... # start the process process.start() # report the process is alive print(process.is_alive()) |
Finally, we can wait for the process to finish and report the status of the process afterward.
1 2 3 4 5 |
... # wait for the process to finish process.join() # report the process is alive print(process.is_alive()) |
Tying this together, the complete example of checking the alive status of a process while it is running is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# SuperFastPython.com # example of assessing whether a running process is alive from time import sleep from multiprocessing import Process # function to execute in a new process def task(): sleep(1) # entry point if __name__ == '__main__': # create the process process = Process(target=task) # report the process is alive print(process.is_alive()) # start the process process.start() # report the process is alive print(process.is_alive()) # wait for the process to finish process.join() # report the process is alive print(process.is_alive()) |
Running the example creates the process instance and confirms that it is not alive before the start() function has been called.
The process is then started and blocked for a second, meanwhile we check the alive status in the parent process which is reported as True, the thread is alive.
The process finishes and the alive status is reported again, showing that indeed the process is no longer alive.
1 2 3 |
False True False |
Example of Querying Process Exit Code
A child process will have an exit code once it has terminated.
An exit code provides an indication of whether processes completed successfully or not, and if not, the type of error that occurred that caused the termination.
Common exit codes include:
- 0: Normal (exit success)
- 1: Error (exit failure)
We can write the exit code for a child process via the multiprocessing.Process.exitcode attribute.
1 2 3 |
... # report the process exit code print(process.exitcode) |
A process will not have an exit code until the process is terminated. This means, checking the exit code of a process before it has started or while it is running will return a None value.
We can demonstrate this with a worked example that executes a custom target function that blocks for one second.
First, we create a new process instance to execute our task() function, report the exit code, then start the process and report the exit code while the process is running.
1 2 3 4 5 6 7 8 9 |
... # create the process process = Process(target=task) # report the exit status print(process.exitcode) # start the process process.start() # report the exit status print(process.exitcode) |
We can then block until the child process has terminated, then report the exit code.
1 2 3 4 5 |
... # wait for the process to finish process.join() # report the exit status print(process.exitcode) |
Tying this together, the complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# SuperFastPython.com # example of checking the exit status of a child process from time import sleep from multiprocessing import Process # function to execute in a new process def task(): sleep(1) # entry point if __name__ == '__main__': # create the process process = Process(target=task) # report the exit status print(process.exitcode) # start the process process.start() # report the exit status print(process.exitcode) # wait for the process to finish process.join() # report the exit status print(process.exitcode) |
Running the example first creates a new process to execute our custom task function.
The status code of the child process is reported, which is None as expected. The process is started and blocked for one second. While running, the exit code is reported again, which again is None as expected.
The parent process then blocks until the child process terminates. The exit code is reported, and in this case we can see that a value of zero is reported indicating a normal or successful exit.
1 2 3 |
None None 0 |
The exit code for a process can be set by calling sys.exit() and specifying an integer value, such as 1 for a non-successful exit.
We can demonstrate this with a worked example where our custom task() function exits with a failure.
The updated task() function with this change is listed below.
1 2 3 4 5 6 |
# function to execute in a new process def task(): # block for a moment sleep(1) # exit with an error sys.exit(1) |
We can then create and start the process and wait for it to terminate
1 2 3 4 5 6 7 |
... # create the process process = Process(target=task) # start the process process.start() # wait for the process to finish process.join() |
Once terminated, we can report the exit code.
1 2 3 |
... # report the exit status print(process.exitcode) |
Tying this together, the complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# SuperFastPython.com # example of checking the exit status of a child process from time import sleep from multiprocessing import Process import sys # function to execute in a new process def task(): # block for a moment sleep(1) # exit with an error sys.exit(1) # entry point if __name__ == '__main__': # create the process process = Process(target=task) # start the process process.start() # wait for the process to finish process.join() # report the exit status print(process.exitcode) |
Running the example first creates and starts the new process.
The child process blocks for a moment, then exits with a failure status.
The parent process blocks until the child process is finished, then reports the exit code, which is 1 indicating a failure in this case.
1 |
1 |
Further Reading
This section provides additional resources that you may find helpful.
Python Multiprocessing Books
- Python Multiprocessing Jump-Start, Jason Brownlee (my book!)
- Multiprocessing API Interview Questions
- Multiprocessing API Cheat Sheet
I would also recommend specific chapters in the books:
- Effective Python, Brett Slatkin, 2019.
- See: Chapter 7: Concurrency and Parallelism
- High Performance Python, Ian Ozsvald and Micha Gorelick, 2020.
- See: Chapter 9: The multiprocessing Module
- Python in a Nutshell, Alex Martelli, et al., 2017.
- See: Chapter: 14: Threads and Processes
Guides
- Python Multiprocessing: The Complete Guide
- Python Multiprocessing Pool: The Complete Guide
- Python ProcessPoolExecutor: The Complete Guide
APIs
References
Takeaways
You now know how to query the attributes of a process instance.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Do you have any questions?