আমি কিন্ডেলের উত্তরটি চুরি করেছি এবং এটি কিছুটা পরিষ্কার করেছি।
সময়সীমাটি পরিচালনা করার জন্য মূল অংশটি * আরগস এবং ** কাওয়ার্গগুলিতে যোগ দিচ্ছে () যোগদানের জন্য
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
নীচে উত্তর আপডেট করুন
এটি আমার সর্বাধিক জনপ্রিয় উর্ধ্বমুখী উত্তর, তাই আমি কোডটি আপডেট করার সিদ্ধান্ত নিয়েছি যা পাই 2 এবং পাই 3 উভয়ই চলবে।
অধিকন্তু, আমি এই প্রশ্নের অনেক উত্তর দেখতে পাচ্ছি যা থ্রেড.জয়াইন () সম্পর্কিত বোধগম্যের অভাব দেখায়। কিছু পুরোপুরি timeout
আর্গোড পরিচালনা করতে ব্যর্থ হয় । তবে এমন একটি কর্নার-কেসও রয়েছে যা আপনার যখন (1) লক্ষ্যযুক্ত ফাংশনটি ফিরে আসতে পারে None
এবং (2) timeout
আপনিও যোগ দিতে আর্গ ( পাস) পাস করেন তখন উদাহরণগুলির বিষয়ে আপনার সচেতন হওয়া উচিত । এই কোণার কেসটি বুঝতে দয়া করে "টেস্ট 4" দেখুন।
থ্রেডউইথের্টেন ক্লাস যা পাই 2 এবং পাই 3 এর সাথে কাজ করে:
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
কিছু নমুনা পরীক্ষা নীচে দেখানো হয়েছে:
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))
আমরা সম্ভবত যে টেস্ট 4 এর মুখোমুখি হতে পারি সেই কোণার কেসটি সনাক্ত করতে পারি?
সমস্যাটি হ'ল আমরা আশা করি যে মাই () কে কেউ ফিরিয়ে দেবে না (টেস্ট ২ দেখুন), তবে আমরাও আশা করি জয়েন () এর সময় শেষ হলে কোনটিই ফিরে আসবে না।
returned is None
এর অর্থ হয়:
(1) এটিই গিমেএম () ফিরে এসেছে, বা
(2) যোগদান () সময়সীমা শেষ
এই উদাহরণটি তুচ্ছ কারণ আমরা জানি যে গিটিএম () সর্বদা কোনওটিই ফিরিয়ে দেবে না। তবে বাস্তব-দুনিয়ায় (যেখানে লক্ষ্যটি বৈধভাবে কেউ বা অন্য কোনও কিছু ফিরিয়ে দিতে পারে না) আমরা কী ঘটেছিল তা স্পষ্টভাবে যাচাই করতে চাই।
নীচে এই কোণার-কেসটিকে কীভাবে সম্বোধন করা যায়:
# 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]
অর্ডার বজায় রাখা হবে, এবং প্রস্থানটিwith
ফলাফল সংগ্রহের অনুমতি দেবে।[f.result() for f in futures]