프로세스 풀의 인수
및 대기열의 항목
과 같은 하위 프로세스와 공유할 수 있음네트워크 액세스를 통해 다른 시스템의 프로세스 간에 동일한 객체에 안전하게 액세스
할 수 있습니다.시작된 SyncManager 객체
를 반환 import multiprocessing
manager = multiprocessing.Manager()
final_list = manager.list()
input_list_one = ['one', 'two', 'three', 'four', 'five']
input_list_two = ['six', 'seven', 'eight', 'nine', 'ten']
def worker(data):
for item in data:
final_list.append(item)
process1 = multiprocessing.Process(target=worker, args=[input_list_one])
process2 = multiprocessing.Process(target=worker, args=[input_list_two])
process1.start()
process2.start()
process1.join()
process2.join()
print(final_list)
list()
: 프로세스 간에 공유할 수 있는 리스트를 반환합니다.dict()
: 프로세스 간에 공유할 수 있는 딕셔너리를 반환합니다.Array(typecode, sequence)
: multiprocessing.Array
와 유사하게, 프로세스 간에 공유할 수 있는 배열을 생성합니다.multiprocessing
모듈의 Manager
클래스는 프로세스 간에 데이터를 공유하기 위한 다양한 방법을 제공합니다. 여기에는 Namespace
, Value
, Array
등이 포함되며, 각각의 사용 방법에 대해 구체적인 예시를 들어 설명하겠습니다.Namespace
는 프로세스 간에 공유할 수 있는 간단한 객체로, 속성 접근 방식을 통해 데이터를 저장하고 검색할 수 있습니다.Namespace
는 동적 속성 할당을 지원하므로, 런타임에 속성을 추가하거나 변경할 수 있습니다.from multiprocessing import Process, Manager
def worker(ns):
ns.x += 1
ns.y *= 2
if __name__ == '__main__':
with Manager() as manager:
ns = manager.Namespace()
ns.x = 1
ns.y = 10
p = Process(target=worker, args=(ns,))
p.start()
p.join()
print(ns.x, ns.y)
# 출력: 2 20
Value
는 프로세스 간에 공유할 수 있는 단일 값을 저장하기 위해 사용됩니다. typecode
는 저장할 데이터의 타입을 나타내며, value
는 초기값입니다. Value
는 기본적인 데이터 타입(예: 정수, 실수)을 공유하기 위한 것from multiprocessing import Process, Manager
def worker(val):
val.value += 5.5
if __name__ == '__main__':
with Manager() as manager:
num = manager.Value('d', 0.0) # 'd'는 double을 의미
p = Process(target=worker, args=(num,))
p.start()
p.join()
print(num.value)
# 출력: 5.5
Array
는 프로세스 간에 공유할 수 있는 배열을 저장하기 위해 사용typecode
는 배열에 저장될 데이터의 타입을 지정하고, sequence
는 배열의 초기값을 제공합니다. from multiprocessing import Process, Manager
def worker(arr):
for i in range(len(arr)):
arr[i] = arr[i] ** 2
if __name__ == '__main__':
with Manager() as manager:
arr = manager.Array('i', range(5)) # 'i'는 정수를 의미
p = Process(target=worker, args=(arr,))
p.start()
p.join()
print(list(arr))
# 출력: [0, 1, 4, 9, 16]
Lock()
: 프로세스 간의 동기화를 위한 락 객체를 반환합니다.RLock()
: 재귀적 락을 제공합니다. 같은 프로세스 내에서 여러 번 획득할 수 있습니다.Semaphore(value)
: 세마포어를 생성합니다. 동시에 리소스에 접근할 수 있는 프로세스의 수를 제한합니다.multiprocessing.Manager
를 사용하면 여러 프로세스 간에 데이터를 안전하게 공유할 수 있습니다. 프록시 객체(예: 공유 딕셔너리, 리스트 등)
는 자체적으로 프로세스 안전(process-safe)하며, 내부적으로 동기화 메커니즘을 사용하여 경쟁 조건(race conditions)을 방지 Lock
이나 Semaphore
같은 동기화 메커니즘이 필요한 이유는 다음과 같습니다:Lock
을 사용하여 복합 작업 전체를 원자적으로 처리할 수 있습니다.Lock
이나 Semaphore
를 사용할 수 있습니다. Lock
을, 제한된 수의 프로세스만 동시에 접근하게 하려면 Semaphore
를 사용합니다.Lock
이나 Semaphore
등을 사용하여 동시 접근을 조절할 수 있습니다.from multiprocessing import Process, Manager, Lock, Semaphore
from typing import Dict
def task_with_lock(lock: Lock, data: Dict[str, int]) -> None:
with lock:
value = data['counter']
time.sleep(0.1) # 시뮬레이션을 위한 지연
data['counter'] = value + 1
def task_with_semaphore(semaphore: Semaphore, data: Dict[int, str], process_number: int) -> None:
with semaphore:
data[process_number] = f"Process {process_number} was here"
time.sleep(0.5) # 시뮬레이션을 위한 지연
# 예시 코드 실행 부분은 동일하며, 함수 호출 시 타입 어노테이션이 적용된 파라미터를 전달합니다.
Event()
: 이벤트 객체를 반환합니다. 프로세스 간의 이벤트 통지를 위해 사용됩니다.Condition()
: 조건 변수 객체를 반환합니다. 프로세스 간에 복잡한 동기화 패턴을 구현할 때 사용됩니다.Queue(maxsize)
: 프로세스 간에 데이터를 주고받을 수 있는 큐를 생성합니다. maxsize
는 큐의 최대 아이템 수를 지정합니다.Barrier(parties, action=None, timeout=None)
: 모든 프로세스가 바리어 지점에 도달할 때까지 기다리게 하는 동기화 객체입니다.from multiprocessing import Process, Manager
def worker(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.reverse()
if __name__ == '__main__':
with Manager() as manager:
# 공유 딕셔너리와 리스트 생성
d = manager.dict()
l = manager.list(range(10))
# 작업자 프로세스 생성 및 실행
p = Process(target=worker, args=(d, l))
p.start()
p.join()
print(d)
print(l)
이 예시에서는 Manager()
를 사용하여 프로세스 간에 공유되는 딕셔너리와 리스트를 생성합니다. 그런 다음 Process
를 사용하여 별도의 프로세스에서 이 데이터 구조들을 수정하는 작업을 수행합니다. Manager
를 사용하면 서로 다른 프로세스에서 실행되는 코드 간에 복잡한 데이터 구조를 쉽게 공유하고 동기화할 수 있습니다.