How to terminate a thread in python
How to terminate a thread in python: 1. Call the stop function and use the join function to wait for the thread to exit appropriately; 2. Raise an Exception in the python thread; 3. Use "thread.join" to end the thread .
The operating environment of this article: Windows 7 system, python version 3.5, DELL G3 computer.
Preface·Zero
We know that to terminate a thread in python, the conventional method is to set/check--->flag or lock of.
Is this method good?
It should not be very good! Because in all programming languages, terminating a thread suddenly is not a good design pattern in any case.
At the same time
In some cases it is even worse, such as:
- When a thread opens a critical resource that must be closed reasonably, such as opening a Readable and writable files;
- The thread has created several other threads, and these threads also need to be closed (there is a risk of descendant threads wandering!).
To put it simply, a large group of our threads are co-located with common resources. You want one of the threads to "leave". If this thread happens to occupy resources, then it will be forced to leave. It’s just that the resources are locked up and no one can get them! Isn’t it a bit similar to the plot of a novel about cultivating immortals?
Do you know why threading only has start but no end?
You see, threads are generally used for network connections, releasing system resources, and dumping streaming files. These are all related to IO. If you suddenly close the thread, what should you do if these
are not closed properly? Are you just creating bugs for yourself? ah? !
So the most important thing in this kind of thing is not to terminate the thread but to clean up the thread.
Solution · 一
A nicer way is to have each thread with an exit request flag, and check it at a certain interval in the thread to see if it should Left by myself!
import threading class StoppableThread(threading.Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" def __init__(self): super(StoppableThread, self).__init__() self._stop_event = threading.Event() def stop(self): self._stop_event.set() def stopped(self): return self._stop_event.is_set()
As shown in this part of the code, when you want to exit the thread you should explicitly call the stop() function, and use the join() function to wait for the thread to exit appropriately. Threads should periodically check the stop flag.
However, there are some usage scenarios where you really need to kill a thread: for example, when you encapsulate an external library, but the external library calls for a long time, so you Want to interrupt this process.
[Recommended: python video tutorial]
Solution · 2
The next solution is to allow raising an Exception in the python thread (of course There are some restrictions).
def _async_raise(tid, exctype): '''Raises an exception in the threads with id tid''' if not inspect.isclass(exctype): raise TypeError("Only types can be raised (not instances)") res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) if res == 0: raise ValueError("invalid thread id") elif res != 1: # "if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0) raise SystemError("PyThreadState_SetAsyncExc failed") class ThreadWithExc(threading.Thread): '''A thread class that supports raising exception in the thread from another thread. ''' def _get_my_tid(self): """determines this (self's) thread id CAREFUL : this function is executed in the context of the caller thread, to get the identity of the thread represented by this instance. """ if not self.isAlive(): raise threading.ThreadError("the thread is not active") # do we have it cached? if hasattr(self, "_thread_id"): return self._thread_id # no, look for it in the _active dict for tid, tobj in threading._active.items(): if tobj is self: self._thread_id = tid return tid # TODO: in python 2.6, there's a simpler way to do : self.ident raise AssertionError("could not determine the thread's id") def raiseExc(self, exctype): """Raises the given exception type in the context of this thread. If the thread is busy in a system call (time.sleep(), socket.accept(), ...), the exception is simply ignored. If you are sure that your exception should terminate the thread, one way to ensure that it works is: t = ThreadWithExc( ... ) ... t.raiseExc( SomeException ) while t.isAlive(): time.sleep( 0.1 ) t.raiseExc( SomeException ) If the exception is to be caught by the thread, you need a way to check that your thread has caught it. CAREFUL : this function is executed in the context of the caller thread, to raise an excpetion in the context of the thread represented by this instance. """ _async_raise( self._get_my_tid(), exctype )
As described in the comments, this is not a "panacea", because if the thread is busy outside the python interpreter, then the terminal exception will not be caught~
This code The reasonable way to use it is to let the thread catch a specific exception and then perform the cleanup operation. This way you can terminate a task and clean it up appropriately.
Solution · 3
If we want to do something similar to the interrupt method, then we can use the thread.join method.
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。 先看看这个: 1. 阻塞主进程,专注于执行多线程中的程序。 2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。 3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。 4. 参数timeout为线程的阻塞时间,如 timeout=2 就是罩着这个线程2s 以后,就不管他了,继续执行下面的代码。
# coding: utf-8 # 多线程join import threading, time def doWaiting1(): print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n" time.sleep(3) print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n" def doWaiting2(): print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" time.sleep(8) print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n" tsk = [] thread1 = threading.Thread(target = doWaiting1) thread1.start() tsk.append(thread1) thread2 = threading.Thread(target = doWaiting2) thread2.start() tsk.append(thread2) print 'start join: ' + time.strftime('%H:%M:%S') + "\n" for tt in tsk: tt.join() print 'end join: ' + time.strftime('%H:%M:%S') + "\n"
The default join method is no parameters, blocking mode, and other threads will only run after the child thread has finished running.
1. Two threads are started at the same time, and the join function is executed.
2. After the waiting1 thread executes (waits) for 3 seconds, it ends.
3. After the waiting2 thread executes (waits) for 8s, the operation ends.
4. The join function (returned to the main process) ends.
This is the default join method, which is to join after the thread has started running. Pay attention to this. After joining, the main thread must wait for the child thread to finish before returning. main line.
The parameter of join, that is, the timeout parameter, is changed to 2, that is, join (2), then the result is as follows:
two Two threads are started at the same time, and the join function is executed.
wating1 thread completed after executing (waiting) for three seconds.
join exit (two 2s, a total of 4s, 36-32=4, correct).
waiting2 thread did not complete within the waiting time (4s) specified by join, so it completed its execution later.
join(2) is: I will give you two seconds for the sub-thread. After each 2s is over, I will leave. I will not have the slightest chance. concern!
The above is the detailed content of How to terminate a thread in python. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



MySQL has a free community version and a paid enterprise version. The community version can be used and modified for free, but the support is limited and is suitable for applications with low stability requirements and strong technical capabilities. The Enterprise Edition provides comprehensive commercial support for applications that require a stable, reliable, high-performance database and willing to pay for support. Factors considered when choosing a version include application criticality, budgeting, and technical skills. There is no perfect option, only the most suitable option, and you need to choose carefully according to the specific situation.

HadiDB: A lightweight, high-level scalable Python database HadiDB (hadidb) is a lightweight database written in Python, with a high level of scalability. Install HadiDB using pip installation: pipinstallhadidb User Management Create user: createuser() method to create a new user. The authentication() method authenticates the user's identity. fromhadidb.operationimportuseruser_obj=user("admin","admin")user_obj.

It is impossible to view MongoDB password directly through Navicat because it is stored as hash values. How to retrieve lost passwords: 1. Reset passwords; 2. Check configuration files (may contain hash values); 3. Check codes (may hardcode passwords).

MySQL can run without network connections for basic data storage and management. However, network connection is required for interaction with other systems, remote access, or using advanced features such as replication and clustering. Additionally, security measures (such as firewalls), performance optimization (choose the right network connection), and data backup are critical to connecting to the Internet.

The MySQL connection may be due to the following reasons: MySQL service is not started, the firewall intercepts the connection, the port number is incorrect, the user name or password is incorrect, the listening address in my.cnf is improperly configured, etc. The troubleshooting steps include: 1. Check whether the MySQL service is running; 2. Adjust the firewall settings to allow MySQL to listen to port 3306; 3. Confirm that the port number is consistent with the actual port number; 4. Check whether the user name and password are correct; 5. Make sure the bind-address settings in my.cnf are correct.

MySQL Workbench can connect to MariaDB, provided that the configuration is correct. First select "MariaDB" as the connector type. In the connection configuration, set HOST, PORT, USER, PASSWORD, and DATABASE correctly. When testing the connection, check that the MariaDB service is started, whether the username and password are correct, whether the port number is correct, whether the firewall allows connections, and whether the database exists. In advanced usage, use connection pooling technology to optimize performance. Common errors include insufficient permissions, network connection problems, etc. When debugging errors, carefully analyze error information and use debugging tools. Optimizing network configuration can improve performance

MySQL database performance optimization guide In resource-intensive applications, MySQL database plays a crucial role and is responsible for managing massive transactions. However, as the scale of application expands, database performance bottlenecks often become a constraint. This article will explore a series of effective MySQL performance optimization strategies to ensure that your application remains efficient and responsive under high loads. We will combine actual cases to explain in-depth key technologies such as indexing, query optimization, database design and caching. 1. Database architecture design and optimized database architecture is the cornerstone of MySQL performance optimization. Here are some core principles: Selecting the right data type and selecting the smallest data type that meets the needs can not only save storage space, but also improve data processing speed.

As a data professional, you need to process large amounts of data from various sources. This can pose challenges to data management and analysis. Fortunately, two AWS services can help: AWS Glue and Amazon Athena.
