Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python 배리어(Barrier) 객체로 스레드 동기화 마스터하기

배리어(Barrier)는 파이썬에서 제공하는 동기화 기법 중 하나로, 하나 또는 여러 개의 스레드가 미리 정해진 지점에 도달할 때까지 서로를 기다린 후 함께 다음 작업을 진행하도록 만들어 줍니다. 즉, 각 스레드가 도착하는 시점은 달라도 모든 스레드가 배리어 지점에 모일 때까지 대기한 뒤 동시에 출발하는 것입니다.

배리어 객체 생성하기

배리어 객체는 threading.Barrier를 사용하여 생성합니다.

threading.Barrier(parties, action=None, timeout=None)

각 매개변수의 의미는 다음과 같습니다.

  • parties : 배리어 지점을 통과해야 하는 스레드의 수

  • action : 스레드들이 해제될 때 그중 하나의 스레드에 의해 호출되는 콜백 함수

  • timeout : 기본 타임아웃 값. wait() 메서드에 별도의 타임아웃이 지정되지 않은 경우 이 값이 사용됩니다.

Barrier 클래스의 주요 메서드와 속성

Barrier 클래스에서 자주 사용되는 메서드와 속성은 아래 표와 같습니다.

번호메서드 및 설명
1parties
공통 배리어 지점에 도달해야 하는 스레드의 수입니다.
2n_waiting
현재 배리어 지점에서 대기 중인 스레드의 수입니다.
3broken
불리언(Boolean) 값으로, 배리어가 깨진(broken) 상태이면 True, 그렇지 않으면 False입니다.
4wait(timeout=None)
호출한 스레드를 배리어에 등록하고, 설정된 스레드 수만큼 모든 스레드가 도착하거나 타임아웃이 발생할 때까지 대기 상태로 블록합니다.
timeout 인자가 None이 아닌 값으로 지정된 경우, 초 단위(소수점 이하 포함 가능)의 부동 소수점 숫자여야 합니다.
5reset()
배리어를 기본 상태, 즉 빈 상태로 되돌립니다. 이때 배리어에서 대기 중이던 스레드들은 BrokenBarrierError 예외를 받게 됩니다.
6abort()
배리어를 강제로 깨진(broken) 상태로 만듭니다. 이로 인해 현재 활성화된 모든 스레드와 이후의 wait() 호출은 BrokenBarrierError와 함께 실패하게 됩니다.

실전 예제 코드

barrierThread.py

from random import randrange
from threading import Barrier, Thread
from time import ctime, sleep

num = 4
# 4개의 스레드가 모두 이 배리어를 통과해야 해제됩니다.
b = Barrier(num)

names = ['India', 'Japan', 'USA', 'China']

def player():
    name = names.pop()
    sleep(randrange(2, 5))
    print('%s reached the barrier at: %s \n' % (name, ctime()))
    b.wait()

threads = []
print("Race starts now…")

for i in range(num):
    threads.append(Thread(target=player))
    threads[-1].start()

"""
아래 반복문은 메인 스크립트가 계속 진행되기 전에
모든 스레드가 종료될 때까지 기다리도록 합니다.
"""
for thread in threads:
    thread.join()

print("All Reached Barrier Point!")

위 예제에서는 네 개의 스레드가 각각 무작위 시간(2~5초)만큼 대기한 뒤 배리어에 도착합니다. 마지막 스레드가 도착하는 순간 네 스레드가 모두 함께 해제되며 프로그램이 종료 메시지를 출력합니다.

실행 결과

Race starts now…
India reached the barrier at: Fri Jan 18 14:07:44 2019
China reached the barrier at: Fri Jan 18 14:07:44 2019
Japan reached the barrier at: Fri Jan 18 14:07:46 2019
USA reached the barrier at: Fri Jan 18 14:07:46 2019
All Reached Barrier Point!

결과를 보면 각 스레드가 배리어에 도착한 시각이 서로 다르지만, 모든 스레드가 도착한 이후에야 일괄적으로 통과된 것을 확인할 수 있습니다. 이처럼 배리어는 여러 스레드의 작업 진행 시점을 특정 지점에서 맞춰야 하는 상황에서 매우 유용하게 활용됩니다.