search
HomeBackend DevelopmentPython TutorialDon't force kill python threads

Foreword:

Don’t try to kill a python thread by force. This is unreasonable in terms of service design. Multi-threading is used for collaborative concurrency of tasks. If you use force to kill threads, there is a high chance that unexpected bugs will occur. Please remember that the lock resource will not be released because the thread exits!

We can cite two common examples:

1. Thread A got the lock because it was forcibly killed and failed to release the lock resource in time with release() , then all threads will be blocked in acquiring resources, which is a typical deadlock scenario.

2. In a common production-consumer scenario, the consumer obtains tasks from the task queue, but does not throw the ongoing task back into the queue after being killed, which results in data loss.

The following are methods for terminating threads in java and python:

Java has three methods to terminate threads:

1. Use exit flag, so that the thread exits normally, that is, the thread terminates when the run method is completed.
2. Use the stop method to forcefully terminate the thread (not recommended, because stop is the same as suspend and resume, and unpredictable results may occur).
3. Use the interrupt method to interrupt the thread.

Python can have two methods:

1. Exit mark
2. Use ctypes to forcefully kill the thread

No matter In a Python or Java environment, the ideal way to stop and exit a thread is to let the thread commit suicide. The so-called thread suicide means that you give it a flag and it exits the thread.

Below we will use a variety of methods to test the abnormal situation of stopping the python thread. We look at all the execution threads of a process. The process uses control resources, and the thread is used as a scheduling unit. To be scheduled for execution, a process must have a thread. The default thread is the same as the pid of the process.

ps -mp 31449 -o THREAD,tid
 
USER   %CPU PRI SCNT WCHAN USER SYSTEM  TID
root   0.0  -  - -     -   -   -
root   0.0 19  - poll_s  -   - 31449
root   0.0 19  - poll_s  -   - 31450

After obtaining all the threads of the process, we know through strace that 31450 is the thread ID that we need to kill. When we kill, the entire process will appear All crash. In a multi-threaded environment, the generated signal is passed to the entire process. Generally speaking, all threads have the opportunity to receive this signal. The process executes the signal processing function in the thread context that receives the signal, which thread executes it. Hard to know. In other words, the signal will be sent to a thread of the process at random.

strace -p <span style="font-size:14px;line-height:21px;">31450</span> Process <span style="font-size:14px;line-height:21px;">31450</span> attached - interrupt to quit
select(0, NULL, NULL, NULL, {0, 320326}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0})   = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0})   = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0})   = ? ERESTARTNOHAND (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
Process <span style="font-size:14px;line-height:21px;">31450</span> detached

The above problem is actually consistent with the description of pthread. When we add the signal signal processing function to the python code, the callback function can prevent the entire process from exiting. Then the problem arises. The signal function cannot identify which thread you want to kill. In other words, it cannot accurately kill a certain thread. . Although you send the signal to the 31450 thread ID, the signal acceptor is any one of the process to which it belongs. In addition, the parameters passed to the signal processing function are only the signal number and the signal stack, which are optional.

After adding signal processing, the process will not exit

select(0, NULL, NULL, NULL, {1, 0})   = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0})   = ? ERESTARTNOHAND (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
rt_sigreturn(0xffffffff)        = -1 EINTR (Interrupted system call)
select(0, NULL, NULL, NULL, {1, 0})   = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0})   = 0 (Timeout)

If you want to kill a thread from an external notification, then You can build and use rpc services, or communicate in other ways, but signals cannot because they cannot transmit more information.

Python threads are not simulated, they are real kernel threads. The kernel calls the pthread method, but the upper layer of Python does not provide a method to close the thread, so we need to control it ourselves. It is strongly recommended to use event or custom flag bit methods. If you must forcefully kill the thread, you can use the python ctypes PyThreadState SetAsyncExc method to force exit, which will have no impact on the running python service.

The implementation principle of this function is relatively simple. In fact, it is to set a flag in the Python virtual machine, and then the virtual machine will run an exception to cancel the thread. The virtual machine will help you make a try cache. Remember not to kill a thread in Python externally. Although you can find the thread ID through ctypes, killing it directly will kill the entire process.

The following code is an example of using ctypes to kill threads. It is not recommended because it is too rude.

import ctypes
 
def terminate_thread(thread):
  if not thread.isAlive():
    return
 
  exc = ctypes.py_object(SystemExit)
  res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
    ctypes.c_long(thread.ident), exc)
  if res == 0:
    raise ValueError("nonexistent thread id")
  elif res > 1:
    ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
    raise SystemError("PyThreadState_SetAsyncExc failed")

Let's take a brief look at the PyThreadState source code. In short, the exception mode of the trigger thread is triggered. Those who are interested can read the design of python pystate.c and share it with some videos on YouTube.

 int
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
  PyInterpreterState *interp = GET_INTERP_STATE();
  ...
  HEAD_LOCK();
  for (p = interp->tstate_head; p != NULL; p = p->next) {
    if (p->thread_id == id) {
      从链表里找到线程的id,避免死锁,我们需要释放head_mutex。
      PyObject *old_exc = p->async_exc;
      Py_XINCREF(exc); #增加该对象的引用数
      p->async_exc = exc; # 更为exc模式
      HEAD_UNLOCK();
      Py_XDECREF(old_exc); # 因为要取消,当然也就递减引用
      ...
      return 1; #销毁线程成功
    }
  }
  HEAD_UNLOCK();
  return 0;
}

Native posix pthread can use ptread_cancel(tid) to end the child thread in the main thread. However, Python's thread library does not support this. The reason is that we should not forcefully end a thread. This will bring many hidden dangers, and the thread should be allowed to end itself. Therefore, in Python, the recommended method is to loop through a sub-thread to determine a flag, change the flag in the main thread, and end itself when the sub-thread reads the flag change.

Similar to this logic:

def consumer_threading():
 t1_stop= threading.Event()
 t1 = threading.Thread(target=thread1, args=(1, t1_stop))
 
 t2_stop = threading.Event()
 t2 = threading.Thread(target=thread2, args=(2, t2_stop))
 
 time.sleep(duration)
 #stop the thread2
 t2_stop.set()
 
def thread1(arg1, stop_event):
 while(not stop_event.is_set()):
   #similar to time.sleep()
   stop_event.wait(time)
   pass
 
 
def thread2(arg1, stop_event):
 while(not stop_event.is_set()):
   stop_event.wait(time)
   pass

A brief summary, although we can use pystats in ctypes to control threads, this method of rudely interrupting threads is unreasonable. Please use suicide mode! What if your thread is blocking io and cannot determine the event? Your program needs to be optimized. At least it needs to have an active timeout at the network IO layer to avoid continuous blocking.

Please pay attention to the PHP Chinese website for more related articles about not using forced methods to kill python threads!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Python and Time: Making the Most of Your Study TimePython and Time: Making the Most of Your Study TimeApr 14, 2025 am 12:02 AM

To maximize the efficiency of learning Python in a limited time, you can use Python's datetime, time, and schedule modules. 1. The datetime module is used to record and plan learning time. 2. The time module helps to set study and rest time. 3. The schedule module automatically arranges weekly learning tasks.

Python: Games, GUIs, and MorePython: Games, GUIs, and MoreApr 13, 2025 am 12:14 AM

Python excels in gaming and GUI development. 1) Game development uses Pygame, providing drawing, audio and other functions, which are suitable for creating 2D games. 2) GUI development can choose Tkinter or PyQt. Tkinter is simple and easy to use, PyQt has rich functions and is suitable for professional development.

Python vs. C  : Applications and Use Cases ComparedPython vs. C : Applications and Use Cases ComparedApr 12, 2025 am 12:01 AM

Python is suitable for data science, web development and automation tasks, while C is suitable for system programming, game development and embedded systems. Python is known for its simplicity and powerful ecosystem, while C is known for its high performance and underlying control capabilities.

The 2-Hour Python Plan: A Realistic ApproachThe 2-Hour Python Plan: A Realistic ApproachApr 11, 2025 am 12:04 AM

You can learn basic programming concepts and skills of Python within 2 hours. 1. Learn variables and data types, 2. Master control flow (conditional statements and loops), 3. Understand the definition and use of functions, 4. Quickly get started with Python programming through simple examples and code snippets.

Python: Exploring Its Primary ApplicationsPython: Exploring Its Primary ApplicationsApr 10, 2025 am 09:41 AM

Python is widely used in the fields of web development, data science, machine learning, automation and scripting. 1) In web development, Django and Flask frameworks simplify the development process. 2) In the fields of data science and machine learning, NumPy, Pandas, Scikit-learn and TensorFlow libraries provide strong support. 3) In terms of automation and scripting, Python is suitable for tasks such as automated testing and system management.

How Much Python Can You Learn in 2 Hours?How Much Python Can You Learn in 2 Hours?Apr 09, 2025 pm 04:33 PM

You can learn the basics of Python within two hours. 1. Learn variables and data types, 2. Master control structures such as if statements and loops, 3. Understand the definition and use of functions. These will help you start writing simple Python programs.

How to teach computer novice programming basics in project and problem-driven methods within 10 hours?How to teach computer novice programming basics in project and problem-driven methods within 10 hours?Apr 02, 2025 am 07:18 AM

How to teach computer novice programming basics within 10 hours? If you only have 10 hours to teach computer novice some programming knowledge, what would you choose to teach...

How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading?How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading?Apr 02, 2025 am 07:15 AM

How to avoid being detected when using FiddlerEverywhere for man-in-the-middle readings When you use FiddlerEverywhere...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft