Другие способы реализации потоков выполнения с помощью модуля threading

drugie sposoby realizacii potokov vypolneniya s pomoshhju modulya threading Системные инструменты параллельного выполнения

Класс Thread можно также использовать для запуска простых функций и вызываемых объектов других типов, вообще не создавая подклассы. Метод run класса Thread по умолчанию просто вызывает объект, переданный конструктору в аргументе target, со всеми дополнительными аргументами, переданными в аргументе args (который по умолчанию является пустым списком ()). Это позволяет использовать класс Thread для запуска простых функций, хотя такая форма вызова ненамного проще использования модуля _thread. Например, в следующих фрагментах демонстрируются четыре различных способа запуска одного и того же потока (смотрите сценарии fourthreads*.py в дереве примеров; вы можете запустить все четыре потока в одном сценарии, но при этом вам понадобится синхронизировать обращения к функции print, чтобы избежать смешивания выводимых данных):

import threading, _thread def action(i):

print(i ** 32)

#  подкласс, хранящий собственную информацию о состоянии class Mythread(threading.Thread): def __init__(self, i): self.i = i

threading.Thread.__init__(self)

def run(self): # переопределить метод run

print(self.i ** 32)

Mythread(2).start() # метод start вызовет метод run()

#  передача простой функции

thread = threading.Thread(target=(lambda: action(2))) # run вызовет target thread.start()

#  то же самое, но без lambda-функции,

#  сохраняющей информацию о состоянии в образуемом ею замыкании

threading.Thread(target=action, args=(2,)).start() # вызываемый объект

# и его аргументы

#  с помощью модуля thread

_thread.start_new_thread(action, (2,)) # полностью процедурный интерфейс

Как правило, выбирать реализацию потоков на основе классов имеет смысл, когда потоки должны сохранять информацию о своем состоянии или когда желательно использовать какие-либо из многочисленных преимуществ ООП. Однако классы потоков выполнения необязательно должны наследовать класс Thread. Фактически, как и при использовании модуля _thread, реализация потоков в модуле threading может принимать в аргументе target вызываемые объекты любого типа. При объединении с такими приемами, как связанные методы и вложенные области видимости, различия между приемами программирования становятся еще менее выраженными:

#  обычный класс с атрибутами, ООП class Power:

def __init__(self, i): self.i = i

def action(self): print(self.i ** 32)

obj = Power(2)

threading.Thread(target=obj.action).start() # запуск связанного метода

#  вложенная область видимости, для сохранения информации о состоянии def action(i):

def power():

print(i ** 32)

return power

threading.Thread(target=action(2)).start() # запуск возвращаемой функции

#  запуск обоих вариантов с помощью модуля _thread _thread.start_new_thread(obj.action, ()) # запуск вызываемого объекта

_thread.start_new_thread(action(2), ())

Как видите, интерфейс модуля threading такой же гибкий, как и сам язык Python.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий