웹사이트 검색

Python 다중 처리 예제


이전 자습서에서는 Python CSV 예제에 대해 배웠습니다. 이 튜토리얼에서 우리는 예제를 통해 Python Multiprocessing을 배울 것입니다.

파이썬 멀티프로세싱

요즘 병렬 처리에 대한 관심이 높아지고 있습니다. 여전히 병렬 처리에 대해 모른다면 wikipedia에서 배우십시오. CPU 제조업체가 프로세서에 점점 더 많은 코어를 추가하기 시작함에 따라 병렬 코드 생성은 성능을 향상시키는 좋은 방법입니다. Python은 병렬 코드를 작성할 수 있도록 다중 처리 모듈을 도입했습니다. 이 모듈의 주요 동기를 이해하려면 병렬 프로그래밍에 대한 몇 가지 기본 사항을 알아야 합니다. 이 기사를 읽은 후 이 주제에 대한 지식을 수집할 수 있기를 바랍니다.

Python 다중 처리 프로세스, 대기열 및 잠금

파이썬 다중 처리 모듈에는 병렬 프로그램을 구축하기 위한 많은 클래스가 있습니다. 그중 세 가지 기본 클래스는 Process, QueueLock입니다. 이러한 클래스는 병렬 프로그램을 구축하는 데 도움이 됩니다. 그러나 그것들에 대해 설명하기 전에 간단한 코드로 이 주제를 시작하겠습니다. 병렬 프로그램을 유용하게 만들려면 PC에 몇 개의 코어가 있는지 알아야 합니다. Python Multiprocessing 모듈을 통해 알 수 있습니다. 다음 간단한 코드는 PC의 코어 수를 인쇄합니다.

import multiprocessing

print("Number of cpu : ", multiprocessing.cpu_count())

Python 다중 처리 프로세스 클래스

Python 다중 처리 Process 클래스는 다른 Python 프로세스를 설정하는 추상화로, 코드를 실행하고 부모 애플리케이션이 실행을 제어할 수 있는 방법을 제공합니다. Process 클래스에 속하는 두 가지 중요한 기능인 start()join() 기능이 있습니다. 먼저 프로세스에 의해 실행될 함수를 작성해야 합니다. 그런 다음 프로세스 개체를 인스턴스화해야 합니다. 프로세스 개체를 생성하면 start() 함수를 통해 처리를 시작하라고 지시할 때까지 아무 일도 일어나지 않습니다. 그런 다음 프로세스가 실행되고 결과를 반환합니다. 그런 다음 join() 함수를 통해 프로세스를 완료하도록 지시합니다. join() 함수 호출이 없으면 프로세스는 유휴 상태로 유지되고 종료되지 않습니다. 따라서 많은 프로세스를 생성하고 종료하지 않으면 리소스 부족에 직면할 수 있습니다. 그런 다음 수동으로 죽여야 할 수도 있습니다. 한 가지 중요한 점은 프로세스를 통해 인수를 전달하려면 args 키워드 인수를 사용해야 한다는 것입니다. 다음 코드는 Process 클래스의 사용법을 이해하는 데 도움이 될 것입니다.

from multiprocessing import Process


def print_func(continent='Asia'):
    print('The name of continent is : ', continent)

if __name__ == "__main__":  # confirms that the code is under main function
    names = ['America', 'Europe', 'Africa']
    procs = []
    proc = Process(target=print_func)  # instantiating without any argument
    procs.append(proc)
    proc.start()

    # instantiating process with arguments
    for name in names:
        # print(name)
        proc = Process(target=print_func, args=(name,))
        procs.append(proc)
        proc.start()

    # complete the processes
    for proc in procs:
        proc.join()

Python 다중 처리 대기열 클래스

컴퓨터 데이터 구조에 대한 기본 지식이 있고 Queue에 대해 알고 있을 것입니다. Python Multiprocessing 모듈은 정확히 선입선출 데이터 구조인 Queue 클래스를 제공합니다. 모든 피클 Python 개체를 저장할 수 있으며(단순한 것이 가장 좋음) 프로세스 간에 데이터를 공유하는 데 매우 유용합니다. 대기열은 프로세스가 데이터를 소비할 수 있도록 프로세스의 대상 함수에 매개변수로 전달될 때 특히 유용합니다. put() 함수를 사용하여 데이터를 대기열에 삽입할 수 있고 get()을 사용하여 대기열에서 항목을 가져올 수 있습니다. 간단한 예제는 다음 코드를 참조하십시오.

from multiprocessing import Queue

colors = ['red', 'green', 'blue', 'black']
cnt = 1
# instantiating a queue object
queue = Queue()
print('pushing items to queue:')
for color in colors:
    print('item no: ', cnt, ' ', color)
    queue.put(color)
    cnt += 1

print('\npopping items from queue:')
cnt = 0
while not queue.empty():
    print('item no: ', cnt, ' ', queue.get())
    cnt += 1

Python 다중 처리 잠금 클래스

Lock 클래스의 작업은 매우 간단합니다. 잠금이 해제될 때까지 다른 프로세스가 유사한 코드를 실행할 수 없도록 코드가 잠금을 요청할 수 있습니다. 따라서 Lock 클래스의 작업은 주로 두 가지입니다. 하나는 잠금을 요구하는 것이고 다른 하나는 잠금을 해제하는 것입니다. 잠금을 요청하려면 acquire() 함수를 사용하고 잠금을 해제하려면 release() 함수를 사용합니다.

Python 다중 처리 예제

Python 다중 처리 예제에서는 모든 지식을 함께 병합합니다. 수행해야 할 몇 가지 작업이 있다고 가정합니다. 해당 작업을 완료하기 위해 여러 프로세스를 사용합니다. 따라서 우리는 두 개의 대기열을 유지할 것입니다. 하나는 작업을 포함하고 다른 하나는 완료된 작업의 로그를 포함합니다. 그런 다음 작업을 완료하기 위해 프로세스를 인스턴스화합니다. Python Queue 클래스는 이미 동기화되어 있습니다. 즉, 동일한 대기열 개체에 액세스하기 위해 여러 프로세스를 차단하기 위해 Lock 클래스를 사용할 필요가 없습니다. 그렇기 때문에 이 경우 Lock 클래스를 사용할 필요가 없습니다. 다음은 대기열에 작업을 추가한 다음 프로세스를 생성하고 시작한 다음 join()을 사용하여 프로세스를 완료하는 구현입니다. 마지막으로 두 번째 대기열에서 로그를 인쇄합니다.

from multiprocessing import Lock, Process, Queue, current_process
import time
import queue # imported for using queue.Empty exception


def do_job(tasks_to_accomplish, tasks_that_are_done):
    while True:
        try:
            '''
                try to get task from the queue. get_nowait() function will 
                raise queue.Empty exception if the queue is empty. 
                queue(False) function would do the same task also.
            '''
            task = tasks_to_accomplish.get_nowait()
        except queue.Empty:

            break
        else:
            '''
                if no exception has been raised, add the task completion 
                message to task_that_are_done queue
            '''
            print(task)
            tasks_that_are_done.put(task + ' is done by ' + current_process().name)
            time.sleep(.5)
    return True


def main():
    number_of_task = 10
    number_of_processes = 4
    tasks_to_accomplish = Queue()
    tasks_that_are_done = Queue()
    processes = []

    for i in range(number_of_task):
        tasks_to_accomplish.put("Task no " + str(i))

    # creating processes
    for w in range(number_of_processes):
        p = Process(target=do_job, args=(tasks_to_accomplish, tasks_that_are_done))
        processes.append(p)
        p.start()

    # completing process
    for p in processes:
        p.join()

    # print the output
    while not tasks_that_are_done.empty():
        print(tasks_that_are_done.get())

    return True


if __name__ == '__main__':
    main()

Python 다중 처리 풀

Python 다중 처리 풀은 여러 입력 값에서 함수의 병렬 실행에 사용되어 프로세스 간에 입력 데이터를 분산할 수 있습니다(데이터 병렬 처리). 다음은 간단한 Python 다중 처리 풀 예제입니다.

from multiprocessing import Pool

import time

work = (["A", 5], ["B", 2], ["C", 1], ["D", 3])


def work_log(work_data):
    print(" Process %s waiting %s seconds" % (work_data[0], work_data[1]))
    time.sleep(int(work_data[1]))
    print(" Process %s Finished." % work_data[0])


def pool_handler():
    p = Pool(2)
    p.map(work_log, work)


if __name__ == '__main__':
    pool_handler()