End process in python

How to Safely Stop a Process in Python

You can safely stop a process by using a multiprocessing.Event.

In this tutorial you will discover how to gracefully stop a process in Python.

Need to Stop a Process

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:

In concurrent programming, we may run a task in a new process, then later decide to stop the task.

This may be for many reasons, such as:

  • The result from the task is no longer required.
  • The application is shutting down.
  • The outcome from the task has gone astray.

Python provides no way to stop a running process in the API.

How can we stop a process in Python?

Run your loops using all CPUs, download my FREE book to learn how.

How to Stop a Process

A process can be stopped using a shared boolean variable such as a multiprocessing.Event.

A multiprocessing.Event is a thread-safe boolean variable flag that can be either set or not set. It can be shared between processes safely and correctly and checked and set without fear of a race condition.

You can learn more about multiprocessing events in the tutorial:

A new multiprocessing.Event can be created and then shared between processes, for example:

The event is created in the ‘not set’ or False state.

We may have a task in a custom function that is run in a new process. The task may iterate, such as in a while-loop or a for-loop.

We can update our task function to check the status of a multiprocessing.Event each iteration.

If the event is set True, we can exit the task loop or return from the task() function, allowing the new child process to terminate.

The status of the multiprocessing.Event can be checked via the is_set() function.

The main parent process, or another process, can then set the event in order to stop the new process from running.

The multiprocessing.Event can be set or made True via the set() function.

Note, this same approach can be used to stop a thread within a process. You can learn more in the tutorial:

Now that we know how to stop a Python process, let’s look at some worked examples.

Confused by the multiprocessing module API?
Download my FREE PDF cheat sheet

Stop a Process With a Custom Function

In this section we can explore how to safely stop a child process that is executing a custom function.

First, we will develop an example that runs a custom function in a child process, then we will look at how to update the example to stop the process on demand.

Custom Function in a New Process

We can develop an example that runs a function in a new child process.

The new task function will execute in a loop and once finished the new process will terminate and the main parent process will terminate.

Firstly, we can define the task function.

The function will execute a loop five times. Each iteration it will block for a second, then report a message in an effort to simulate work and show progress.

Once the task is finished, the function will report a final message.

The task() function below implements this.

Next, in the main parent process we can create a new multiprocessing.Process instance that is configured to execute our task() function in a new process via the “target” argument.

We can then immediately start the new process via the start() function.

The parent process will then wait for the new child process to finish by joining the process.

If you are new to joining processes, you can learn more here:

Tying this together, the complete example is listed below.

Running the example first creates and starts the new child process.

The main parent process then blocks until the new process finishes.

The new process executes in a loop, blocking for a moment and reporting progress. After five iterations of the loop, the new process reports a final message and terminates.

The parent process notices that the new process has finished and then terminates itself, closing the program.

Next, let’s look at how we might update this example to stop the process on demand.

Stop Custom Function in New Process

We can update the example from the previous section to stop the new process on demand.

This can be achieved by creating a new multiprocessing.Event instance, passing it as an argument to the new process, and then updating the custom function to check if the event is set each iteration. Once the event is set, the function can break its task loop and exit, terminating the new process.

Firstly, we can update the task function to take the shared multiprocessing.Event instance as an argument.

We can then update the task loop to check the status of the event each iteration, and if set to break the task loop.

Tying this together, the updated task() function with these changes is listed below.

Next, the main process can first create a new multiprocessing.Event instance to be shared between the processes.

We can then update the parent process to block for a few seconds.

Finally, we can set the event and trigger the new process to stop.

Tying this together, the complete example is listed below.

Running the example first creates and starts the new child process.

The main parent process then blocks for a few seconds.

Meanwhile, the new process executes its task loop, blocking and reporting a message each iteration. It checks the event each iteration, which remains false and does not trigger the process to stop.

The main parent process wakes up, and then sets the event. It then joins the new process, waiting for it to terminate.

The task process checks the event which is discovered to be set (e.g. True). The process breaks the task loop, reports a final message then terminates the new process.

The parent process then terminates, closing the Python program.

Now that we know how to stop a custom function running in a new process, let’s look at an example of stopping a custom process class.

Free Python Multiprocessing Course

Download my multiprocessing API cheat sheet and as a bonus you will get FREE access to my 7-day email course.

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.

Stop a Process With an Extended Class

In this section we can explore how to stop a process that is an object that extends the multiprocessing.Process class.

First, we will develop an example that extends the multiprocessing.Process class, then we will look at how to update the example to stop the process on demand.

Custom Process Class

We can run a task in a new process by extending the multiprocessing.Process class and overriding the constructor and the run() function.

In this section, we will show how to run the same task as in the previous section within a custom process class.

Firstly, we can define a new class that extends multiprocessing.Process.

The new class may implement a constructor, and if so it must call the constructor of the multiprocessing.Process class to properly initialize the underlying process instance.

We can then override the run() method on the multiprocessing.Process class.

This function will run in a new process once the process is started via the start() function. Specifically we call start() and start() will call run() for us in a new spawned or forked child process.

Our task will be to execute a loop five times, block for a second to simulate work, and report a message. Then report a message once the task is complete.

Tying this together the new CustomProcess class is listed below.

Next, in the main parent process, we can create a new instance of our custom process class and start it in order to execute our task in a new process.

We will then join() the new process and wait for the new process to terminate, before terminating the main parent process.

Tying this together, the complete example is listed below.

Running the example first creates our custom process class then starts executing the new process.

The main process then blocks waiting for the new process to finish.

Our custom process class runs our task in a new process of execution, looping five times. Each iteration it blocks for a moment then reports a message.

Once the task is finished, it reports a final message.

The new process terminates, then the main process terminates, closing the process.

Next, let’s look at how we might update this example to stop the task on demand.

Stop Custom Process Class

We can update the example in the previous section to stop the process on demand.

This can be achieved by sharing a multiprocessing.Event with the new process and updating the run() function to check if the event is set each iteration. Once set, the run() function can exit, which will terminate the new process.

Firstly, we can update the constructor of our new process class to create a new instance of the multiprocessing.Event class and store it as an instance variable attribute.

Next, we can update the run() function to check the status of the multiprocessing.Event each iteration and to break the task loop once the event is set.

Tying this together, the updated CustomProcess class that can be stopped on demand is listed below.

The main parent process can then set the event via the attribute on the new CustomProcess instance.

Tying this together, the complete example is listed below.

Running the example first involves creating an instance of the custom process and starting it.

The main process will then block for a few seconds.

The new process will start executing its task loop, blocking for a moment and reporting progress.

The main process then wakes up and sets the event, triggering the new process to stop.

The new process notices that the event is set and then exits the task loop, reporting a final message and terminating the new process.

The main process waits for the new process to terminate, before then stopping itself and closing the application.

Overwheled by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps

Common Questions About Stopping Processes

This section lists common questions about stopping a child process in Python.

Do you have any questions about stopping a process? Let me know in the comments and I will do my best to help.

What if My Task Does Not Have a Loop?

Your task does not need to have a loop in order to be stopped.

Instead, you need to add frequent checks of the shared multiprocessing.Event and return from the task() function or run() function once the event is set.

This will depend on the specifics of the task you wish to exit in a new process.

If your task involves blocking, such as reading or writing IO or waiting on another process, you may want to adopt a busy wait and have the multiprocessing.Event checked each iteration.

If your task remains idle for some time, such as waiting for sporadic events, it may be able to wait on the multiprocessing.Event itself via the wait() function.

What if My Task Raises An Exception?

If your task executing in a new process raises an exception that is not handled, it will terminate the process.

This could be an alternate way for you to trigger a new process to terminate, if convenient.

What if My New Process Has Already Stopped?

If the new process has already stopped and you set the event, it will not have any effect.

It would not be a problem.

What if My New Process is a Daemon Process?

If your task is executing in a daemon process, then there is no need to stop it manually as it will be terminated for you once all non-daemon processes (e.g. the main parent process) terminate.

You can learn more about daemon process here:

How Can We Stop Multiple Processes?

You can share the same multiprocessing.Event between all of the child processes that might want to stop.

Each process can frequently check the status of the event.

Once set, all processes can exit their task and terminate.

How Can We Stop Tasks in a ProcessPoolExecutor?

The same technique of using a multiprocessing.Event can be used to stop tasks executing in a ProcessPoolExecutor.

You can see an example of this here:

Do We Need To Use a Manager

A shared Event object can be created via a multiprocessing.Manager.

Источник

Читайте также:  How to define important text using HTML5?
Оцените статью