J'ai essayé d'utiliser une bibliothèque (fil conducteur) qui rend le package de threads Python plus facile à utiliser. https://pypi.org/project/commonthread/ Il est plus précis d'essayer de l'utiliser ou de le fabriquer.
Comment installer le package commonthread
pip install -U commonthread
01.py
from commonthread import *
# source https://techacademy.jp/magazine/28155
def fibonacci_worker(th: WorkerThread, n: int):
if n <= 2:
return 1
else:
return fibonacci_worker(th, n - 2) + fibonacci_worker(th, n - 1)
thread = WorkerThread(fibonacci_worker, 36)
thread.name = 'tfib'
thread.start()
success = thread.join(timeout=0.5)
print('success={}'.format(success))
success = thread.join()
print('success={}'.format(success))
print('result={}'.format(thread.result))
print('elapsed={}'.format(thread.elapsed))
print(thread)
01.résultat d'exécution py
success=False
success=True
result=14930352
elapsed=3.688599109649658
WorkerThread(name=tfib, result=14930352, elapsed=3.688599109649658, args=(36,), kwargs={}, params={})
thread = WorkerThread (fibonacci_worker, 36)
, le premier argument du constructeur WorkerThread est le nom de la fonction worker. Le deuxième argument et les suivants sont les arguments passés à la fonction de travail. Vous pouvez en transmettre autant que vous le souhaitez, à condition qu'ils correspondent au nombre d'arguments de la fonction de travail.def fibonacci_worker (th: WorkerThread, n: int)
. Vous devez recevoir cet argument, mais vous n'êtes pas obligé de l'utiliser.thread.join ()
, j'imprime thread.result
et thread.elapsed
. La valeur renvoyée par la fonction de travail fibonacci_worker est automatiquement stockée dans le membre résultat de l'objet WorkerThread. De plus, le temps écoulé pour exécuter la fonction de travail fibonacci_worker est stocké dans le membre écoulé.print (thread)
. (Pour le débogage)Parfois, je souhaite renvoyer une valeur de retour à partir d'une fonction de travail, elle est donc optimisée à cette fin.
02.py
from commonthread import *
# source https://techacademy.jp/magazine/28155
class FibonacciThread(CommonThread):
def entry(self, n: int):
if n <= 2:
return 1
else:
return self.entry(n - 2) + self.entry(n - 1)
thread = FibonacciThread(36)
thread.name = 'tfib'
thread.start()
thread.join()
print('result={}'.format(thread.result))
print('elapsed={}'.format(thread.elapsed))
print(thread)
02.résultat d'exécution py
result=14930352
elapsed=4.399198055267334
FibonacciThread(name=tfib, result=14930352, elapsed=4.399198055267334, args=(36,), kwargs={}, params={})
class FibonacciThread (CommonThread)
, étendez la classe CommonThread.au lieu de
run (self) . Ce thread qui calcule le nombre de Fibonacci ne prend qu'un seul argument entier, donc c'est
def entry (self, n: int)`. Vous pouvez avoir une méthode d'entrée avec n'importe quel nombre d'arguments sans avoir à jouer avec le constructeur d'une classe qui hérite de CommonThread. Si c'est un processus simple, vous n'avez pas à vous soucier de créer une définition de constructeur, ce qui est utile.03.py
from commonthread import *
class AddThread(CommonThread):
def __init__(self, x: int, y: int):
CommonThread.__init__(self)
self.x = x
self.y = y
def entry(self):
time.sleep(2.0)
return self.x + self.y
thread = AddThread(11, 22)
thread.start()
thread.join()
print('result={}'.format(thread.result))
print('elapsed={}'.format(thread.elapsed))
print(thread)
03.résultat d'exécution py
result=33
elapsed=2.0015878677368164
AddThread(name=Thread-1, result=33, elapsed=2.0015878677368164, args=(), kwargs={}, params={})
class AddThread (CommonThread)
, le constructeur est défini comme def __init __ (self, x: int, y: int)
pour accepter les arguments x et y. Ainsi, lors de la définition de «init» dans une classe enfant de CommonThread, vous devez écrire «CommonThread .__ init__ (self)» comme sa première ligne d'exécution. C'est comme un sort.def entry (self)
, et aucun argument autre que l'objet thread lui-même n'est accepté. Par conséquent, stockez les arguments dans les membres de self.x et slef.y dans le constructeur.04.py
from commonthread import *
lg = CommonThreadLogger()
lg.setup_basic()
class ShortThread(CommonThread):
def entry(self, duration):
lg.debug('start')
time.sleep(duration)
lg.debug('end')
return 'finished'
class LongThread(CommonThread):
def entry(self, duration):
lg.debug('start')
time.sleep(duration)
lg.debug('end')
return 'finished'
lg.debug('start')
sth1 = ShortThread(1.0); sth1.name = 'sth1'
sth2 = ShortThread(1.5); sth2.name = 'sth2'
lth1 = LongThread(5.0); lth1.name = 'lth1'
lth2 = LongThread(6.0); lth2.name = 'lth2'
sth1.start()
sth2.start()
lth1.start()
lth2.start()
lg.debug(CommonThread.list_alive())
CommonThread.join_all(type=ShortThread)
lg.debug(CommonThread.list_alive())
CommonThread.join_all()
lg.debug(CommonThread.list_alive())
04.résultat d'exécution py
MainThread: start
sth1: start
sth2: start
lth1: start
lth2: start
MainThread: [ShortThread(name=sth1, result=None, elapsed=0.0, args=(1.0,), kwargs={}, params={}), ShortThread(name=sth2, result=None, elapsed=0.0, args=(1.5,), kwargs={}, params={}), LongThread(name=lth1, result=None, elapsed=0.0, args=(5.0,), kwargs={}, params={}), LongThread(name=lth2, result=None, elapsed=0.0, args=(6.0,), kwargs={}, params={})]
sth1: end
sth2: end
MainThread: [LongThread(name=lth1, result=None, elapsed=0.0, args=(5.0,), kwargs={}, params={}), LongThread(name=lth2, result=None, elapsed=0.0, args=(6.0,), kwargs={}, params={})]
lth1: end
lth2: end
MainThread: []
lg = CommonThreadLogger ()
, lg.setup_basic ()
active la journalisation du débogage. Mettez en commentaire la ligne lg.setup_basic ()
lorsque vous n'avez plus besoin de déboguer.lg.debug (~)
après avoir exécuté lg.setup_basic ()
, un journal avec "nom de thread:" au début du message sera affiché comme une erreur standard.CommonThread.join_all (type = ShortThread)
rejoint toutes les instances de ShortThread et attend qu'elles se terminent.CommonThread.join_all ()
joint toutes les instances CommonThread (y compris LongThread) et attend qu'elles se terminent.CommonThread.list_alive ()
retourne une liste de tous les objets CommonThread actifs (non terminés).CommonThread.list_alive (type = ShortThread)
renvoie une liste de tous les objets ShortThread actifs (non terminés).CommonThread.are_alive ()
pour voir s'il y a quelque chose d'actif dans CommonThread. Si vous spécifiez CommonThread.are_alive (type = ShortThread)
, vous ne pouvez cocher que ShortThread.Les fonctionnalités qui n'ont pas pu être introduites cette fois sont:
Recommended Posts