강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

성지님의 프로필 이미지
성지

작성한 질문수

우리를 위한 프로그래밍 : 파이썬 중급 (Inflearn Original)

병렬성 2 - Futures(5-1)

45. 병렬성 2 - Futures(5-1) wait가 의도된 대로 동작하지 않습니다.

작성

·

15

0

import time
from concurrent import futures

WORK_LIST = [1000000, 10000000, 100000000, 1000000000]


def sum_number(n):
    return sum(range(1, n + 1))


def main():
    start_time = time.time()
    futures_list = []

    with futures.ThreadPoolExecutor() as excecutor:
        for work in WORK_LIST:
            future = excecutor.submit(sum_number, work)
            futures_list.append(future)
            print(f"Schduled Work: {work} | {future}")
            print()

        result = futures.wait(futures_list, timeout=5.0)
        print(result)

    end_time = time.time() - start_time

    print(f"Excecute Time: {end_time:.2f}s / Result: {result}")


if __name__ == '__main__':
    main()

현재 문제점은 최종 출력 시간이 12초정도 걸리는데 중간에 5초 wait 후 print(result)가 호출되는 것이 아니라 12초 후에 아래 코드가 실행될 때 함께 실행되며 모두 정상적으로 finished returned int로 나옵니다.

print(f"Excecute Time: {end_time:.2f}s / Result: {result}")

터미널 출력 결과:
DoneAndNotDoneFutures(done={<Future at 0x2545b19e780 state=finished returned int>, <Future at 0x2545b123b10 state=finished returned int>, <Future at 0x2545b16f230 state=finished returned int>, <Future at 0x2545b123390 state=finished returned int>}, not_done=set())

Excecute Time: 11.80s / Result: DoneAndNotDoneFutures(done={<Future at 0x2545b19e780 state=finished returned int>, <Future at 0x2545b123b10 state=finished returned int>, <Future at 0x2545b16f230 state=finished returned int>, <Future at 0x2545b123390 state=finished returned int>}, not_done=set())

 

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 성지님.

Futures 객체의 wait 메서드는 주어진 timeout 기간 동안 Future 객체들이 완료되기를 기다립니다. 코드에서 wait 메서드가 의도한대로 5초 동안 대기하지 않고, 모든 작업이 완료될 때까지 기다린 후에 결과를 출력하는 문제를 겪고 계신 것 같습니다.

현상은 futures.wait 함수의 동작 방식 때문입니다. futures.wait는 기본적으로 모든 future가 완료될 때까지 기다립니다. 만약 어떤 작업이 아직 완료되지 않았더라도, 지정된 timeout이 지나면 종료된 future와 아직 종료되지 않은 future의 집합인 DoneAndNotDoneFutures 객체를 반환하게 됩니다.

해결책

  1. return_when 매개변수 사용: futures.wait 함수에 return_when 매개변수를 설정하여 원하는 시점에 반환하도록 조정할 수 있습니다.

    result = futures.wait(futures_list, timeout=5.0, return_when=futures.ALL_COMPLETED)
    
    • ALL_COMPLETED: 모든 작업이 완료될 때까지 기다립니다. 이 경우 timeout이 지나면 not_done에 아직 완료되지 않은 작업이 포함됩니다.
    • FIRST_COMPLETED: 첫 번째 작업이 완료되면 반환합니다.
    • FIRST_EXCEPTION: 첫 번째 예외가 발생하면 반환합니다.
  2. 적절한 로그 추가: 각 단계에서 미래 객체의 상태를 확인하는 로그를 추가하여 timeout이 어떻게 영향을 미치는지 정확히 확인할 수 있습니다.

출력에서 not_done=set()이므로 모든 작업이 이미 완료된 것을 확인할 수 있습니다. timeout=5.0이 설정되어 있었지만, 모든 작업이 timeout 안에 완료되었기 때문에 모든 Future는 완료 상태입니다.

다음 링크에서 유사한 문제에 대한 다른 분들의 토론과 해결 방법을 확인할 수 있습니다:
- 파이썬의 concurrent.futures 모듈 사용법

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

성지님의 프로필 이미지
성지

작성한 질문수

질문하기