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

WBOY
Libérer: 2023-04-13 10:43:09
avant
2186 Les gens l'ont consulté

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)
Copier après la connexion

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))
Copier après la connexion

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。
Copier après la connexion
.

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())
Copier après la connexion

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
Copier après la connexion

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!

Étiquettes associées:
source:51cto.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal