무효 클릭 IP 추적 중...
파이썬/파이썬 중급

[python]multiprocessing Process 완벽 정리(초보자)

꼬예 2023. 1. 26.

[ic]Process[/ic]를 이해하기 위해선 [ic]Process[/ic]가 왜 필요한지 부터 알아야 한다.

 

Process 왜 필요할까?

[ic]Process[/ic]를 사용하지 않으면 어떤 불편함이 발생할까?

 

Process를 사용하지 않은 예

from multiprocessing import Process
import time

def function1():
    print("Start function 1")
    time.sleep(3)
    print("End function 1")

def function2():
    print("Start function 2")
    time.sleep(5)
    print("End function 2")

if __name__ == '__main__':
    function1()
    function2()
#output
'''
Start function 1
End function 1
Start function 2
End function 2
'''

 

위 코드가 효율적으로 느껴지는가?

 

[ic]function1()[/ic]에서 [ic]print("Start function 1")[/ic] 실행 후 아무것도 하지 않은채 3초를 대기한다.

대기하는 동안 먼저 [ic]function2()[/ic] 를 실행하면 좋지 않을까?

 

이때 사용하는 것이 [ic]Process[/ic]다.

 

Process를 사용한 예

from multiprocessing import Process
import time

def function1():
    print("Start function 1")
    time.sleep(3)
    print("End function 1")

def function2():
    print("Start function 2")
    time.sleep(5)
    print("End function 2")

if __name__ == '__main__':
    p1 = Process(target=function1)
    p2 = Process(target=function2)
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print("Both functions have completed")

# output
'''
Start function 1
Start function 2
End function 1
End function 2
Both functions have completed
'''

지금 당장 코드를 이해 하는건 중요하지 않다.

중요한건 [ic]output[/ic]이다.

 

결과를 보면 우리가 의도한대로 동작하였다.

 

이어서 [ic]Process[/ic] 사용법에 대해 알아보자.

 

Process 사용법

1) 기본 컨셉 이해

from multiprocessing import Process
import time

def function1():
    print("Start function 1")
    time.sleep(3)
    print("End function 1")
    
if __name__ == '__main__':
    p1 = Process(target=function1)
    p1.start()
#output
'''
Start function 1
End function 1
'''

[ic]target[/ic]인자로 실행할 함수를 전달하고 [ic]Process[/ic] 객체를 생성한다.

[ic]start()[/ic]메소드를 통해 프로세스를 실행한다.

 

2) join()

[ic]join()[/ic]은 언제 쓰는걸까?

 

join()을 안쓸 경우

from multiprocessing import Process
import time

def function1():
    print("Start function 1")
    time.sleep(3)
    print("End function 1")
    
if __name__ == '__main__':
    p1 = Process(target=function1)
    p1.start()
    print('완료')
#output
'''
완료
Start function 1
End function 1
'''

[ic]function1()[/ic]부터 실행 되어야 할것같은데 [ic]print('완료')[/ic]가 먼저 실행되었다.

 

join()을 쓸 경우

from multiprocessing import Process
import time

def function1():
    print("Start function 1")
    time.sleep(3)
    print("End function 1")
    
if __name__ == '__main__':
    p1 = Process(target=function1)
    p1.start()
    p1.join()
    print('완료')
#output
'''
Start function 1
End function 1
완료
'''

[ic]join()[/ic]은 생성한 프로세스가 끝날때까지 다른 프로세스를 기다리게 한다.

우리 예제에서는 p1 프로세스에 [ic]join()[/ic]을 적용했다.

 

이는 p1이 끝날때 까지 다른 프로세스는 기다리라는 의미다.

Main 프로세스에 속해 있는 [ic]print('완료')[/ic]는 p1 프로세스 동작이 끝난 후에야 실행 되었다.

 

3) 함수에 인자 넣기

인자 1개 사용

from multiprocessing import Process
import time

def function1(test):
    print(test)
    
if __name__ == '__main__':
    p1 = Process(target=function1, args=('테스트입니다',))
    p1.start()

#output
'''
테스트입니다
'''

 

인자 2개 사용

from multiprocessing import Process
import time

def function1(test, test2):
    print(test)
    print(test2)
    
if __name__ == '__main__':
    p1 = Process(target=function1, args=('테스트입니다','테스트입니다2'))
    p1.start()

#output
'''
테스트입니다
테스트입니다2
'''

감이 오는가?

모두 tuple형태로 값을 전달하고 인자명은 [ic]args[/ic]다

 

위 예제는 positional argument에 대한 거라면 keyword argument의 경우 어떻게 할까?

 

def function1(test, test2):
    print(test)
    print(test2)
    
if __name__ == '__main__':
    p1 = Process(target=function1, kwargs={'test2':'테스트입니다2', 'test':'테스트입니다'})
    p1.start()

#output
'''
테스트입니다
테스트입니다2
'''

기존 [ic]args[/ic] 대신 [ic]kwargs[/ic]를 사용하고, 튜플이 아닌 딕셔너리 형태로 값을 넘겨준다.

 

4) 클래스형 Process

예제 코드를 보면 Process를 클래스 형태로 작성한것을 자주 마주 칠 수 있다.

 

기본적인 컨셉은 유사하다.

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self, test, test2):
        super().__init__()
        
        self.test = test
        self.test2 = test2
        
    def run(self):
        print(self.test)
        print(self.test2)
        
if __name__ == '__main__':
    p1 = MyProcess('테스트입니다','테스트입니다2')
    p1.start()

[ic]Process[/ic]를 상속한 임의의 클래스를 생성한다.

나머지 부분은 유사하니 자세한 설명은 생략한다.

 

함수형과 차이는 2가지로 요약할 수 있다.

함수형 클래스형
args, kwargs 로 인자값을 전달한다. __init__ 생성자를 만들때 인자를 전달한다.
사용함 할수를 target에 할당해주었다. 사용할 함수를 run함수에 구현한다.

 

  • 트위터 공유하기
  • 페이스북 공유하기
  • 카카오톡 공유하기
이 컨텐츠가 마음에 드셨다면 커피 한잔(후원) ☕

댓글