프로세스는 운영체제에서 실행 중인 프로그램 입니다.
운영체제는 프로세스의 실행에 필요한 시스템 자원을 할당 및 관리하며, 실행 상태를 제어합니다.
그렇다면 프로세스는 어떻게 구성되어 있을까요?
프로세스는 4가지 섹션으로 구성되어 있습니다.
각 섹션은 서로 다른 권한을 가지며, 메모리에서 서로 다른 위치에 저장됩니다.
또한 프로세스가 메모리를 공유하지 않으며, 각각의 프로세스가 독립적으로 실행됩니다.
프로세스 내 실행되는 흐름의 단위 입니다. 스레드를 이용할 경우 하나의 프로세스내 여러 부분을 동시에 실행 가능합니다.
스레드는 다음과 같이 구성되어 있습니다.
따라서 스레드들은 자원을 공유한 채 실행에 필요한 최소한의 정보만으로 실행됩니다.
프로세스와 스레드 여러개가 동시에 실행되는 것을 각각 멀티 프로세스, 멀티 스레드라고 합니다.
멀티 프로세스는 동시에 여러개의 프로세스가 실행되는 것입니다. 이를 위해 운영체제는 프로세스들이 독립적으로 실행될 수 있도록, 각 프로세스마다 자원을 할당하고, 프로세스 간 통신을 위한 IPC 기법 등을 제공합니다.
장단점에는 무엇이 있을까요?
장점
단점
IPC??
프로세스간 통신 방법에는 크게 2가지가 있습니다.
멀티 스레드는 하나의 프로세스 내에서 여러 개의 스레드를 생성하고, 각 스레드가 독립적으로 작업을 수행하는 것 입니다.
각 스레드는 프로세스 내 공유 메모리를 이용해 서로 통신하며, 스레드 간 문맥 전환이 빨라 프로세스 간 전환에 비해 빠른 작업 수행이 가능합니다. 따라서 자원과 시스템이 효율성이 증가합니다.
장점
단점
동기화란,
여러 프로세스 혹은 스레드 간에 작업을 조율하는 것 입니다.
멀티 프로세스와 멀티 스레드 환경에서 공유 자원이 이용되는 것을 확인할 수 있었습니다. 이때, 데이터의 무결성을 보장하고 작업이 올바른 순서로 실행하기 위하여 동기화를 이용합니다.
먼저 공유 자원이 무엇일까요?
이 임계구역에 하나의 프로세스혹은 스레드만 접근하도록 하기 위해 동기화 기법을 이용합니다.
프로세스나 스레드 사이에서 공유된 자원에 대한 접근을 제어합니다.
구성
- 전역 변수 S: 임계 구역에 진입할 수 있는 프로세스의 개수
- wait(): 임계 구역에 들어가도 좋은 지, 기다려야 하는지 알려줌
- signal(): 임계 구역 앞에서 기다리는 프로세스에 '이제 가도 좋다'고 신호를 줌
만약 세마포어에서 실행 순서를 제어하려면,
먼저 실행될 프로세스 뒤에 wait 함수 뒤에 실행될 프로세스 앞에 signal함수를 두어 앞의 프로세스가 끝나야만 뒤의 프로세스가 임계 구역에 접근할 수 있도록 합니다.
파이썬에서도 멀티스레드 방식을 이용할 수 있습니다.
그런데, 실제로 위에서 작성했던 피보나치 함수를 멀티스레드로 실행할 경우 시간이 빨라지지 않는 것을 확인할 수 있습니다.
멀티스레딩 X | 멀티 스레딩 O |
---|---|
0.00007 | 0.00085 |
# 1 Thread
start_time = time.time()
fibonacci(10)
fibonacci(10)
end_time = time.time()
print(f'{end_time-start_time:.5f}')
# 2 Thread
start_time = time.time()
threads=[]
for i in range(2):
threads.append(threading.Thread(target=fibonacci, args=(10,)))
threads[-1].start()
for t in threads:
t.join()
end_time = time.time()
print(f'{end_time-start_time:.5f}')
파이썬은 기본적으로 한번에 하나의 스레드만 동작 가능 합니다. 파이썬에서는 스레드를 이용한 병렬 처리를 지원하지만, GIL로 인해 여러 스레드가 동시에 실행되지는 않습니다.
그러면 이쯤에서...
둘 다 겉으로 보기에는 동시에 동작한다는 말인것 같으나, 실제 동작에는 차이가 있습니다.
동시성
: 동시에 실행될 수 있는 여러 작업이 하나의 프로세스에서 번갈아가면서 실행되는 것입니다. 각 작업은 일정 시간 간격으로 실행되기 때문에, 마치 동시에 실행되는 것처럼 보입니다.
ex) 하나의 CPU에서 여러 프로세스들이 번갈아가면서 수행
병렬성
: 동시에 실행될 수 있는 여러 작업이 여러 개의 프로세서에서 동시에 실행되는 것입니다. 각 작업이 서로 독립적으로 실행되므로, 전체 작업의 속도가 오릅니다.
ex) 멀티코어 CPU에서 각 코어당 하나의 스레드가 배정되어 동시에 작동
GIL(Global Interpreter Lock)은 파이썬 인터프리터에서 사용되는 동시성 모델 중 하나입니다.
CPU bound작업의 경우, 그렇습니다.
하지만 I/O bound작업을 할 경우에는 여러 스레드를 이용해 동시에 I/O작업을 처리하는 것이 가능합니다.
각 스레드는 CPU에서 동시에 실행되지 않고 번갈아가면서 동작됩니다.
따라서 멀티 스레드를 이용한다고 하여 성능의 향상은 없습니다.
외부 호출을 하는 I/O bound 작업의 경우 외부 호출을 하기 위해 시스템 콜을 호출하는 동안은 병렬로 작업이 불가능하나 외부에서의 동작은 병렬로 진행될 수도 있습니다.
그렇기 때문에, I/O bound 작업에서는 성능의 향상을 기대해 볼 수 있습니다.