Biraz cevap verdim ve biraz temizledim.
Anahtar kısım zaman aşımını işlemek için katılmak için * args ve ** kwargs () eklemektir.
class threadWithReturn(Thread):
def __init__(self, *args, **kwargs):
super(threadWithReturn, self).__init__(*args, **kwargs)
self._return = None
def run(self):
if self._Thread__target is not None:
self._return = self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
def join(self, *args, **kwargs):
super(threadWithReturn, self).join(*args, **kwargs)
return self._return
AŞAĞIDAKİ GÜNCEL CEVAP
Bu benim en popüler upvoted cevap, bu yüzden hem py2 hem de py3 üzerinde çalışacak kod ile güncelleme karar verdi.
Ayrıca, Thread.join () ile ilgili anlama eksikliği gösteren bu soruya birçok cevap görüyorum. Bazıları timeout
argümanı tamamen ele alamıyor. Ancak (1) geri dönebilen bir hedef fonksiyona sahip olduğunuz None
ve (2)timeout
join () öğesine katılmak argümanı . Bu köşe durumunu anlamak için lütfen "TEST 4" e bakınız.
Py2 ve py3 ile çalışan ThreadWithReturn sınıfı:
import sys
from threading import Thread
from builtins import super # https://stackoverflow.com/a/30159479
if sys.version_info >= (3, 0):
_thread_target_key = '_target'
_thread_args_key = '_args'
_thread_kwargs_key = '_kwargs'
else:
_thread_target_key = '_Thread__target'
_thread_args_key = '_Thread__args'
_thread_kwargs_key = '_Thread__kwargs'
class ThreadWithReturn(Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._return = None
def run(self):
target = getattr(self, _thread_target_key)
if not target is None:
self._return = target(
*getattr(self, _thread_args_key),
**getattr(self, _thread_kwargs_key)
)
def join(self, *args, **kwargs):
super().join(*args, **kwargs)
return self._return
Bazı örnek testler aşağıda gösterilmiştir:
import time, random
# TEST TARGET FUNCTION
def giveMe(arg, seconds=None):
if not seconds is None:
time.sleep(seconds)
return arg
# TEST 1
my_thread = ThreadWithReturn(target=giveMe, args=('stringy',))
my_thread.start()
returned = my_thread.join()
# (returned == 'stringy')
# TEST 2
my_thread = ThreadWithReturn(target=giveMe, args=(None,))
my_thread.start()
returned = my_thread.join()
# (returned is None)
# TEST 3
my_thread = ThreadWithReturn(target=giveMe, args=('stringy',), kwargs={'seconds': 5})
my_thread.start()
returned = my_thread.join(timeout=2)
# (returned is None) # because join() timed out before giveMe() finished
# TEST 4
my_thread = ThreadWithReturn(target=giveMe, args=(None,), kwargs={'seconds': 5})
my_thread.start()
returned = my_thread.join(timeout=random.randint(1, 10))
TEST 4 ile karşılaşabileceğimiz köşe vakasını belirleyebilir misiniz?
Sorun şu ki, giveMe () 'in None döndürmesini bekliyoruz (bkz. TEST 2), ama ayrıca join ()' in zaman aşımı durumunda None döndürmesini bekliyoruz.
returned is None
aşağıdakilerden biri anlamına gelir:
(1) giveMe () geri döndü, ya da
(2) join () zaman aşımına uğradı
Bu örnek önemsizdir çünkü giveMe () işlevinin her zaman None döndüreceğini biliyoruz. Ancak gerçek dünya örneğinde (hedefin meşru olarak Hiçbiri veya başka bir şey getirebileceği durumlarda), ne olduğunu açıkça kontrol etmek isteriz.
Bu köşe vakasının nasıl ele alınacağı aşağıda açıklanmıştır:
# TEST 4
my_thread = ThreadWithReturn(target=giveMe, args=(None,), kwargs={'seconds': 5})
my_thread.start()
returned = my_thread.join(timeout=random.randint(1, 10))
if my_thread.isAlive():
# returned is None because join() timed out
# this also means that giveMe() is still running in the background
pass
# handle this based on your app's logic
else:
# join() is finished, and so is giveMe()
# BUT we could also be in a race condition, so we need to update returned, just in case
returned = my_thread.join()
futures = [executor.submit(foo, param) for param in param_list]
Sipariş korunacak ve iadeden çıkılmasıwith
sonuç toplamaya izin verecektir.[f.result() for f in futures]