スレッドを作成してスレッドから値を取得しようとすると、違いがあります。一般的に言えば、スレッド内でreturn
を使用して呼び出し元に値を返してはいけません。それはスレッドの仕組みではありません。スレッドオブジェクトを作成するときは、スレッド内で計算された値をプログラムの他の部分に取り込む別の方法を見つけなければなりません。以下は、リストを使用して値を返す方法を示す簡単な例です。
#! /usr/bin/env python3
import threading
def main():
# Define a few variables including storage for threads and values.
threads_to_create = 5
threads = []
results = []
# Create, start, and store all of the thread objects.
for number in range(threads_to_create):
thread = threading.Thread(target=lambda: results.append(number))
thread.start()
threads.append(thread)
# Ensure all threads are done and show the results.
for thread in threads:
thread.join()
print(results)
if __name__ == '__main__':
main()
あなたは絶対にあなたがスレッドのターゲットから値を返す機能を持っていなければならないことを主張する場合、所望の動作を得るために子クラスを使用してthreading.Thread
でいくつかのメソッドをオーバーライドすることが可能です。以下は、より高度な使い方を示し、新しいクラスのメソッドrun
を継承して上書きしたい場合に、複数のメソッドが変更を必要とする方法を示しています。このコードは完全性のために提供されており、おそらく使用すべきではありません。
#! /usr/bin/env python3
import sys as _sys
import threading
def main():
# Define a few variables including storage for threads.
threads_to_create = 5
threads = []
# Create, start, and store all of the thread objects.
for number in range(threads_to_create):
thread = ThreadWithReturn(target=lambda: number)
thread.start()
threads.append(thread)
# Ensure all threads are done and show the results.
print([thread.returned for thread in threads])
class ThreadWithReturn(threading.Thread):
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, *, daemon=None):
super().__init__(group, target, name, args, kwargs, daemon=daemon)
self.__value = None
def run(self):
try:
if self._target:
return self._target(*self._args, **self._kwargs)
finally:
del self._target, self._args, self._kwargs
def _bootstrap_inner(self):
try:
self._set_ident()
self._set_tstate_lock()
self._started.set()
with threading._active_limbo_lock:
threading._active[self._ident] = self
del threading._limbo[self]
if threading._trace_hook:
_sys.settrace(threading._trace_hook)
if threading._profile_hook:
threading. _sys.setprofile(threading._profile_hook)
try:
self.__value = True, self.run()
except SystemExit:
pass
except:
exc_type, exc_value, exc_tb = self._exc_info()
self.__value = False, exc_value
if _sys and _sys.stderr is not None:
print("Exception in thread %s:\n%s" %
(self.name, threading._format_exc()), file=_sys.stderr)
elif self._stderr is not None:
try:
print((
"Exception in thread " + self.name +
" (most likely raised during interpreter shutdown):"), file=self._stderr)
print((
"Traceback (most recent call last):"), file=self._stderr)
while exc_tb:
print((
' File "%s", line %s, in %s' %
(exc_tb.tb_frame.f_code.co_filename,
exc_tb.tb_lineno,
exc_tb.tb_frame.f_code.co_name)), file=self._stderr)
exc_tb = exc_tb.tb_next
print(("%s: %s" % (exc_type, exc_value)), file=self._stderr)
finally:
del exc_type, exc_value, exc_tb
finally:
pass
finally:
with threading._active_limbo_lock:
try:
del threading._active[threading.get_ident()]
except:
pass
@property
def returned(self):
if self.__value is None:
self.join()
if self.__value is not None:
valid, value = self.__value
if valid:
return value
raise value
if __name__ == '__main__':
main()
'threading.Thread(target = Thread_Test)'は、スレッドのインスタンスを返します。スレッド名として出力されるスレッド参照の配列を取得します。 – Andrey
キューを使用してデータを収集する必要があります。ここでコンセプトを見つけてください。 https://www.troyfawkes.com/learn-python-multithreading-queues-basics/ – Bhargav
ありがとうございました。 Queは、このようなサンプルコード用に実装されています。 – Jon