Giter Club home page Giter Club logo

python-kill-thread-extension's Introduction

The threader.c file contains a module that will let you kill a thread from anywhere in its execution.

Python-Kill-Thread-Extension

This is a Python module written in C that lets a Python developer kill a thread.

The Problem

While Python provides a powerful threading interface, there is no way (externally) to kill a thread. A proposed solution to get around Python's lack of kill thread functionality has been to set a flag in the thread's code that will cleanly exit the thread. However, for many developers this is not sufficient. What if the thread code will never reach the flag check (for instance, if you're running an external process?)

The Solution

This is the exact situation I was faced with at work one day. So when my Stack Overflow searches turned up hundreds of hits on people asking how to kill Python threads but with no solutions, I decided to write my own.

The threader.c, threaderPy3.c, and threaderPy3windows.c files are modules that will allow you to kill a thread from anywhere in its execution. If you are running Python 2.x, use threader.c. No Windows support is available for Python 2. Python 3 users should use threaderPy3.c or threaderPy3windows.c. The former file is for Linux and the latter is for Windows.

Windows Warning

The threaderPy3windows.c file uses TerminateThread to kill a thread. On Windows, this could result in important processes being left in undefined states. From Microsoft:

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:

  • If the target thread owns a critical section, the critical section will not be released.
  • If the target thread is allocating memory from the heap, the heap lock will not be released.
  • If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
  • If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

So, be aware that TerminateThread doesn't provide the same safeguards as pthread_cancel.

How to use

Whether you are running threader.c or threaderPy3.c, the build instructions are the same. The only thing you need to do with threaderPy3.c is rename it to threader.c so setup.py can find it.

First, you need to build the threader.c module. You can use the supplied setup.py file, or make your own. python setup.py build

Next, install the threader module: sudo python setup.py install

On Windows, use: python setup.py install

Example Usage 1

In your Python code, if you subclass the threading.Thread class, create a method called end. It will look like this:

import threader
import threading
class AThread(threading.Thread):
	def run(self):
		from time import sleep
		while True:
			print "I'm running...and I'll never end!"
			sleep(5)

	def end(self):
		if self.is_alive():
			threader.killThread(self.ident)

Now, you can kill this thread anytime, like this:

runMe = AThread()
runMe.start()
sleep(10)
runMe.end()
Example Usage 2

The problem with the code above is that Python will never know that the thread has ended, because we're not using Python's functionality to kill it. So, we need to provide a way to tell Python that this thread is no longer running. We can do this by overriding the is_alive method in the threading.Thread class. We'll also have to handle the case if an exception occurs during execution.

import threader
import threading
class AThread(threading.Thread):
	def __init__(self):
		threading.Thread.__init__(self)
		self.stopped = False # This is the flag we'll use to signal thread termination.

	def is_alive(self):
		return not self.stopped

	def run(self):
		try:
			from time import sleep
			while True:
				print "I'm running...and I'll never end!"
				sleep(5)
		except Exception as e:
			throw e
		finally:
			self.stopped = true

	def end(self):
		if self.is_alive():
			threader.killThread(self.ident)
			self.stopped = True
Explanation

Notice we give the ident property to the killThread function. The ident property on the threading.Thread class is a unique identifier for the particular thread you are running. By passing it to the C module, we can kill the thread by using C's low-level thread functionality. These identifiers CAN be recycled, but no two running threads will have the same identifier.

Since we bypass Python's implementation for a thread, the task we have to be careful with is telling Python accurately when the thread has finished execution. We do this by setting a flag called stopped. This variable is True when the thread is not running, and False when the thread is running. So, in our second implementation of code, we set stopped to True after calling threader.killThread(self.ident). Now, when Python calls is_alive, it will get False, signaling that the thread has terminated. Without overriding is_alive, the thread will die, but if you have code that waits for the thread to terminate, that code will block forever.

python-kill-thread-extension's People

Contributors

munawarb avatar

Watchers

Xusheng Li avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.