Рубрики
Без рубрики

Как убить нить в Python?

Резюме: Чтобы убить поток, используйте один из следующих методов: создайте флаг EXIT_REQUEST.USING Multipressing Module.Using Trace Module.Using Ctypes для повышения исключений в проблеме потока: Как убить нить в Python? Это один из наиболее распространенных вопросов в Python. Таким образом, в этой статье мы собираемся … Как убить нить в Python? Прочитайте больше “

Автор оригинала: Shubham Sayon.

Резюме: Убить нить, используйте один из следующих методов:

  • Создать Exit_request флаг.
  • Используя Многопроцессор Модуль.
  • Используя трассировка Модуль.
  • Использование CTYPES Чтобы поднять исключения в потоке

Проблема: Как Убить нить в Python?

Это один из наиболее распространенных вопросов в Python. Таким образом, в этой статье мы собираемся решить эту проблему и убедиться, что у вас есть четкое понимание этой темы. Перед делением в тему напрямую, мы посмотрим на резьбу вкратце, а затем перейти к нашему критическому вопросу. Так что без дальнейшей задержки, пусть игры начинаются! 😎.

Вступление

🧵 Что такое Нить ?

По словам Википедия , В информатике нить выполнения является наименьшая последовательность запрограммированных инструкций, которые можно управлять планировщиком, что обычно является частью операционной системы.

➽ Несколько потоков могут работать одновременно в пределах одной программы. Например, в процессоре Word образец может использоваться для проверки заклинаний, когда нить переднего плана может использоваться для обработки пользовательского ввода (нажатий клавиш), а тем не менее третий поток может использоваться для загрузки изображений с жесткого диска, а также Четвертая нить может быть занята, выполняя периодические автоматические резервные копии редактированного файла.

  • Следовательно, резьба в Python используется для запуска нескольких потоков, которые могут быть задачами или вызовами функции, одновременно. Обратите внимание, что это не означает, что несколько потоков выполнены на разных процессорах.
  • Нити Python не делают программу быстрее в том случае, если она уже использует время 100% процессор. Вероятно, является частью параллельного программирования, которая не в пределах объема этой дискуссии.

Примечание: Резьба в Python сама по себе вся тема обсуждения. Цель этого введения – просто познакомиться с идеей потоков. Настоятельно рекомендуется, чтобы у вас было некоторое понимание резьбы в Python перед погружением в тему убийства нити.

Когда мы используем резьбу в Python?

Нитки в Python используются в ситуациях, когда выполнение задачи или вызова функции включает в себя некоторые ожидания. Примером может быть взаимодействие с обслуживанием, размещенным на веб-сервере. Таким образом, резьба позволяет Python выполнить другой код во время ожидания.

Пример:

import threading
import time

print("Printing values from 90 to 100: ")
def loop_thread():
    for t in range(90, 101):
        time.sleep(1)
        print(t)

threading.Thread(target=loop_thread).start()

Выход:

Printing values from 90 to 100: 
90
91
92
93
94
95
96
97
98
99
100

Теперь, когда есть обзор нитей, давайте погрузимся в нашу миссию – критический вопрос.

Способы убить нить в Python

Проще говоря, Убивая резко поток – очень плохая практика, если не требуется абсолютно не требуется Отказ Сказав это, вы можете убить нить после определенной продолжительности времени или после некоторого прерывания. Итак, вместо того, чтобы закрыть его насильственно, вы можете просить тему уйти после обеспечения правильной очистки, что означает:

  • Нить, которую вы пытаетесь убить, могут удерживать критический ресурс, который должен быть закрыт должным образом.
  • Нить может создать несколько других потоков, которые должны быть убиты, а до родительской нитки можно будет убить.

Давайте понять многочисленные способы, которые помогут нам это сделать.

Способ 1: Создание флага запроса выхода

Если вы являетесь менеджером ваших собственных потоков, приятный способ обрабатывать резюмировать резьбу, состоит в том, чтобы создать флаг выхода, который каждый поток проверяет регулярные промежутки времени, чтобы узнать, что пора его выйти.

Пример:

import threading 
import time 
  
def thread_foo(stop):
    while True: 
        print("THREAD STILL RUNNING!") 
        if exit_flag: 
            break

exit_flag = False
t = threading.Thread(target = thread_foo, args =(lambda : exit_flag, )) 
t.start() 
time.sleep(0.1) 
print('Done sleeping! Time to stop the threads.')
exit_flag = True
t.join() 
print('THREAD TERMINATED!')

Выход:

В приведенном выше примере мы создали функцию, которая продолжает выполнять резьбу, пока программа не сталкивается с переменной EXIT_FLAG Отказ Как только это произойдет, поток может быть убит с помощью T.join () метод.

Примечание: Присоединяйтесь () заставляет основной нить ждать вашего потока для завершения выполнения. Другими словами, Присоединяйтесь () действует как «удержание» на главной ните. Он гарантирует, что ваша тема завершила его выполнение до того, как основной нить может двигаться вперед. В некотором смысле, оно обеспечивает чистое и правильное прекращение вашей темы.

Способ 2: Использование многопроцессорного модуля

Как указано в документации Python, Многопроцессор это пакет, который поддерживает нерестовые процессы, используя API, подобное резьба модуль. Кроме того, убийство процесса намного безопаснее, чем убивать поток, потому что Нитки обмениваются глобальными переменными и имеют зависимость, тогда как процессы полностью независимы и существуют отдельно друг от друга. Многопроцессор Модуль имеет Завершить () Функция, которая используется для убийства процесса.

Давайте посмотрим на следующий приведенный ниже пример, чтобы понять, как мы можем использовать Многопроцессор модуль, чтобы убить процесс.

import multiprocessing
import time
def Child_process():
  while True:
   for i in range (20):  
    print ('Process: ', i)
    time.sleep(0.05)
t = multiprocessing.Process(target = Child_process)
t.start()
time.sleep(0.5)
t.terminate()
print("Child Process successfully terminated")

Выход:

Process:  0
Process:  1
Process:  2
Process:  3
Process:  4
Process:  5
Process:  6
Process:  7
Process:  8
Process:  9
Child Process successfully terminated

В приведенном выше примере через 0,5 секунды выполнение Child_Process был прекращен с использованием Завершить () функция.

Способ 3: Использование модуля трассировки

Другой подход к ухудшению потока – это установить трассировка в нить, которая выйдет из потока.

Модуль, указанный ниже, позволяет убивать потоки. Класс Kthread это замена для Threading.Thread Отказ Добавляет Убить () Метод, который должен прекратить большинство потоков на их треках.

Отказ от ответственности: Приведенная ниже процедура была взята из следующего ресурса: Убить нить в Python

🐍 Kthread.py : Реализация убийственной резьбы

import time
import sys
import trace
import threading

class KThread(threading.Thread):
  """A subclass of threading.Thread, with a kill()
method."""
  def __init__(self, *args, **keywords):
    threading.Thread.__init__(self, *args, **keywords)
    self.killed = False

  def start(self):
    """Start the thread."""
    self.__run_backup = self.run
    self.run = self.__run     
    threading.Thread.start(self)

  def __run(self):
    """Hacked run function, which installs the
trace."""
    sys.settrace(self.globaltrace)
    self.__run_backup()
    self.run = self.__run_backup

  def globaltrace(self, frame, why, arg):
    if why == 'call':
      return self.localtrace
    else:
      return None

  def localtrace(self, frame, why, arg):
    if self.killed:
      if why == 'line':
        raise SystemExit()
    return self.localtrace

  def kill(self):
    self.killed = True


# Example Usage
#This illustrates running a function in a separate thread. The thread is killed before the function finishes.
def func():
  print('Function started')
  for i in range(1,100):
    print(i)
    time.sleep(0.2)
  print('Function finished')

A = KThread(target=func)
A.start()
time.sleep(1)
A.kill()

Выход:

Function started
1
2
3
4
5

Способ 4: Использование CTYPES для повышения исключений в потоке

В случаях, когда вам нужно насильственно убить нить, например, во время обертывания внешней библиотеки, которая занята длинными звонками, и вы хотите прервать его, вы можете использовать ROING_EXC () Чтобы поднять произвольное исключение или позвоните Завершить () поднять SystemExit автоматически. Он использует неэкспонированные Pythreadstate_etasyncexc Функция (через CTypes) для повышения исключения в контексте данного потока.

Следующий код позволяет (с некоторыми ограничениями) поднять исключение в потоке Python:

Пример:

import threading
import inspect
import ctypes
import time


def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(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 Thread(threading.Thread):
    def _get_my_tid(self):
        """determines this (self's) thread id"""
        if not self.is_alive():
            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
        
        raise AssertionError("could not determine the thread's id")
    
    def raise_exc(self, exctype):
        """raises the given exception type in the context of this thread"""
        _async_raise(self._get_my_tid(), exctype)
    
    def terminate(self):
        """raises SystemExit in the context of the given thread, which should 
        cause the thread to exit silently (unless caught)"""
        self.raise_exc(SystemExit)

def f():
     try:
         while True:
            for i in range(10000):
             print(i) 
             time.sleep(0.1)
     finally:
         print ("TERMINATING!!!")

t = Thread(target = f)
t.start()
time.sleep(0.6)
t.terminate()
t.join()

Выход:

0
1
2
3
4
5
TERMINATING!!!

Вывод

Ключевые вынос из этой статьи были:

  • Что такое нить?
  • Способы убить нить в Python:
    • Создание флага EXIT_REQUEST.
    • Используя Многопроцессор Модуль.
    • Используя трассировка Модуль.
    • Использование CTYPES Чтобы поднять исключения в потоке

Пожалуйста, Подписаться и Оставайтесь настроиться Для более интересных статей!

использованная литература

  1. https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread
  2. http://net-informations.com/python/iq/kill.htm
  3. https://pybay.com/site_media/slides/raymond2017-keynote/threading.html
  4. http://tomerfiliba.com/recipes/Thread2/

Куда пойти отсюда?

Достаточно теории, давайте познакомимся!

Чтобы стать успешным в кодировке, вам нужно выйти туда и решать реальные проблемы для реальных людей. Вот как вы можете легко стать шестифункциональным тренером. И вот как вы польские навыки, которые вам действительно нужны на практике. В конце концов, что такое использование теории обучения, что никто никогда не нуждается?

Практические проекты – это то, как вы обостряете вашу пилу в кодировке!

Вы хотите стать мастером кода, сосредоточившись на практических кодовых проектах, которые фактически зарабатывают вам деньги и решают проблемы для людей?

Затем станьте питоном независимым разработчиком! Это лучший способ приближения к задаче улучшения ваших навыков Python – даже если вы являетесь полным новичком.

Присоединяйтесь к моему бесплатным вебинаре «Как создать свой навык высокого дохода Python» и посмотреть, как я вырос на моем кодированном бизнесе в Интернете и как вы можете, слишком от комфорта вашего собственного дома.

Присоединяйтесь к свободному вебинару сейчас!

Я профессиональный Python Blogger и Content Creator. Я опубликовал многочисленные статьи и создал курсы в течение определенного периода времени. В настоящее время я работаю полный рабочий день, и у меня есть опыт в областях, таких как Python, AWS, DevOps и Networking.

Вы можете связаться со мной @: