본문 바로가기
Python/Python FAQ

Python 스레드에서 반환 값을 어떻게 얻을 수 있나요?, How to get the return value from a thread?

by 베타코드 2023. 9. 10.
반응형

질문


아래의 함수 foo는 문자열 'foo'를 반환합니다. 스레드의 대상에서 반환된 'foo' 값을 어떻게 얻을 수 있을까요?

from threading import Thread

def foo(bar):
    print('hello {}'.format(bar))
    return 'foo'
    
thread = Thread(target=foo, args=('world!',))
thread.start()
return_value = thread.join()

위에서 보여진 "하나의 명백한 방법"은 작동하지 않습니다: thread.join()None을 반환했습니다.


답변


하나의 방법은 가변 객체(예: 리스트 또는 사전)를 스레드의 생성자와 함께 전달하여 스레드가 해당 객체의 전용 슬롯에 결과를 저장하는 것입니다. 예를 들면 다음과 같습니다:

def foo(bar, result, index):
    print 'hello {0}'.format(bar)
    result[index] = "foo"

from threading import Thread

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

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)  # 메타구문 기차는 어떤 소리를 내나요?

join()이 호출된 함수의 반환 값을 반환하려면 다음과 같이 Thread 하위 클래스를 사용할 수 있습니다:

from threading import Thread

def foo(bar):
    print 'hello {0}'.format(bar)
    return "foo"

class ThreadWithReturnValue(Thread):
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs, Verbose)
        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):
        Thread.join(self)
        return self._return

twrv = ThreadWithReturnValue(target=foo, args=('world!',))

twrv.start()
print twrv.join()   # foo 출력

이는 이름 변환에 약간 복잡하며, Thread 구현에 특정한 "비공개" 데이터 구조에 액세스합니다... 하지만 작동합니다.

Python 3의 경우:

class ThreadWithReturnValue(Thread):
    
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs)
        self._return = None

    def run(self):
        if self._target is not None:
            self._return = self._target(*self._args,
                                                **self._kwargs)
    def join(self, *args):
        Thread.join(self, *args)
        return self._return
반응형

댓글