Maison  >  Article  >  développement back-end  >  Trois façons d'obtenir la valeur de retour du thread en Python

Trois façons d'obtenir la valeur de retour du thread en Python

WBOY
WBOYavant
2023-04-13 10:43:092109parcourir

En ce qui concerne les fils de discussion, votre cerveau devrait avoir cette impression : nous pouvons contrôler quand il commence, mais nous ne pouvons pas contrôler quand il se termine. Alors, comment pouvons-nous obtenir la valeur de retour du fil ? Aujourd'hui, je vais partager certaines de mes propres pratiques.

Méthode 1 : utilisez une liste de variables globales pour enregistrer la valeur de retour

ret_values = []

def thread_func(*args):
...
value = ...
ret_values.append(value)

Une des raisons de choisir une liste est la suivante : la méthode append() de la liste est thread-safe, et dans CPython, le GIL empêche l'accès simultané à eux. Si vous utilisez une structure de données personnalisée, vous devez ajouter un verrou de thread dans lequel les données sont modifiées simultanément.

Si vous savez à l'avance combien de threads il y a, vous pouvez définir une liste de longueur fixe, puis stocker la valeur de retour en fonction de l'index, par exemple :

from threading import Thread

threads = [None] * 10
results = [None] * 10

def foo(bar, result, index):
result[index] = f"foo-{index}"

for i in range(len(threads)):
threads[i] = Thread(target=foo, args=('world!', results, i))
threads[i].start()

for i in range(len(threads)):
threads[i].join()

print (" ".join(results))

Méthode 2 : réécrire la méthode de jointure de Thread et renvoyer la valeur de retour de la fonction thread

Par défaut La méthode thread.join() attend juste la fin de la fonction thread et n'a pas de valeur de retour Nous pouvons renvoyer le résultat d'exécution de la fonction ici. Le code est le suivant :

from threading import Thread


def foo(arg):
return arg


class ThreadWithReturnValue(Thread):
def run(self):
if self._target is not None:
self._return = self._target(*self._args, **self._kwargs)

def join(self):
super().join()
return self._return


twrv = ThreadWithReturnValue(target=foo, args=("hello world",))
twrv.start()
print(twrv.join()) # 此处会打印 hello world。
.

De cette façon, lorsque nous appelons thread.join() pour attendre la fin du fil, nous obtenons également la valeur de retour du fil.

Méthode 3 : utilisez la bibliothèque standard concurrent.futures

Je pense que les deux premières méthodes sont de trop bas niveau. La bibliothèque standard de Python concurrent.futures fournit des opérations de thread plus avancées et peut obtenir directement la valeur de retour du thread. assez élégant. Le code Comme suit :

import concurrent.futures


def foo(bar):
return bar


with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
to_do = []
for i in range(10):# 模拟多个任务
future = executor.submit(foo, f"hello world! {i}")
to_do.append(future)

for future in concurrent.futures.as_completed(to_do):# 并发执行
print(future.result())

Les résultats d'une certaine opération sont les suivants :

hello world! 8
hello world! 3
hello world! 5
hello world! 2
hello world! 9
hello world! 7
hello world! 4
hello world! 0
hello world! 1
hello world! 6

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer
Article précédent:Méthodes magiques en PythonArticle suivant:Méthodes magiques en Python