안드로이드 개발을 하다보면 스레드에 대해 너무도 중요하게 생각이 된다.
UI 스레드를 단일로 처리하여 Main Thread에서만 UI변경이 되기에 스레드 관리는 매우 중요하다.
그렇지만, 이러한 중요성은 안드로이드 개발에 국한된 이야기만은 아니다.
그래서 오늘은 프로세스와 스레드에 대해 이야기 하고자 한다.
프로세스는 운영체제로부터 작업을 할당받는 작업의 단위이고,
스레드는 프로세스가 할당 받은 자원을 이용하는 실행의 단위이다.
프로그램
프로그램이 뭘까?
컴퓨터를 켜서 크롬을 누르고 카톡을 키고 여러 행동을 한다.
크롬과 카톡들은 각자의 프로그램이다.
어떤 작업을 위해 실행할 수 있는 파일
정의는 위와 같이 되어있다.
크롬, 카톡, 안드로이드 스튜디오(ㅎ) 이것들은 다 프로그램이다.
그렇다면 프로세스는?
- 현재 실행 중이거나 곧 실행이 가능한 프로세스 디스크립터(PCB)를 가진 프로그램.
- 실행중인 프로그램으로 디스크로부터 메모리에 적재되어 CPU의 할당을 받은 작업의 단위
- 운영체제(OS)로부터 시스템 자원을 할당 받는다.
- 할당받게 되는 시스템 자원
- CPU 시간
- 운영되기 위한 주소 공간
- Code, Data, Stack, Heap의 구조로 되어있는 독립된 메모리 영역.
- 각 프로세스는 최소 1개의 스레드를 갖는다.(메인스레드)
- 프로세스는 각자 별도의 메모리 영역(주소 공간)을 할당 받는다. 위 그림의 Code, Data, Stack, Heap.
- 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없으며, 접근을 위해선 IPC통신이 필요하다. (파이프, 파일, 소켓 이용한 방식들)
프로세스 제어 블록 (Process Control Block, PCB)
- 특정 프로세스에 대한 중요 정보를 저장하고 있는 커널 내의 자료 구조.
- OS는 프로세스를 관리하기 위해 프로세스의 생성과 동시에 고유한 PCB를 생성한다.
- 프로세스는 CPU를 할당받아 작업을 처리하다가 프로세스 전환이 발생하면 진행하던 작업을 저장하고 CPU를 반환해야 한다. 이때 작업의 진행 상황을 모두 PCB에 저장한다. 그리고 다시 CPU를 할당받게 되면 PCB에 저장되었던 내용을 불러와 종료되었던 시점부터 다시 작업을 수행한다.
PCB에 저장하는 정보
- PID 프로세스 식별자 :: 프로세스 식별 번호
- 프로세스 상태 , new ,running, waiting, terminated..
- 프로그램 카운터(Program Counter, PC) : 프로세스가 다음에 실행할 명령어의 주소
- CPU 레지스터
- CPU 스켸줄링 정보 : 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등
- 메모리 관리 정보 : 페이지 테이블 or 세그먼트 테이블 과 같은 정보 포함
- 입출력 상태 정보 : 프로세스에 할당된 입출력 장치들과 열린 파일 목록
스레드
- 프로세스의 실행 단위. 한 프로세스 내에서 동작하는 여러 실행 흐름으로 프로세스 내의 주소 공간이나 자원을 공유할 수 있다.
- 스레드는 프로세스 내의 Code, Data, Heap 영역은 다른 스레드와 공유하고 Stack은 따로 할당 받는다.
- 여러 스레드는 한 프로세스 내의 Code, Data, Heap 영역을 공유하지만 프로세스 간에는 메모리에 접근할 수 없다.
- 스레드는 별도의 레지스터와 스택을 갖고 있으며, 다른 영역을 공유한다. 따라서 한 스레드가 프로세스의 자원을 변경하면, 다른 스레드도 그 변경 결과를 즉시 확인할 수 있다.
위에서 프로세스와 스레드에 대해 간단하게 알아봤다.
프로그램내의 프로세스. 프로세스 내의 스레드.
그렇다면 프로세스와 스레드 중 어떤걸 멀티로 쓸 때 더 효과적일까?
Multi Process vs Multi Thread
Multi Process
- 하나의 응용 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것.
- fork를 통해 프로세스를 복사한다.
장점
- 여러 개의 자식 프로세스 중 하나에 문제 발생 시, 그 자식 프로세스만 죽는 것 이상으로 다른 영향은 없다.(안전하다)
단점
- Context Switching에서의 Overhead(과부하)
- 프로세스는 각 독립된 메모리 영역을 할당받았기 때문에 공유하는 메모리가 없다. 따라서 캐시 메모리 초기화 등의 무거운 작업이 진행되고 많은 시간 소모 등 오버헤드가 발생할 수 있다.
- 프로세스 간 통신 기법 IPC
- 프로세스는 각 독립된 메모리 영역을 할당 받았기 때문에 프로세스들 사이에서 변수나 자료구조를 공유할 수 없다. 따라서 IPC라는 방법으로 해야하며 이는 복잡하고 어렵다ㅠ
(세마포어, 큐, 공유메모리..)
Multi Thread
- 하나의 응용 프로그램을 여러 개의 스레드로 구성하고 각 스레드가 하나의 작업을 처리하도록 하는 것.
- 윈도우, 리눅스 등 많은 OS들이 멀티 프로세싱을 지원하지만 기본은 멀티 스레딩이다.
- Web Server는 대표적인 멀티 스레드 응용 프로그램이다.
장점
- 메모리 공간과 시스템 자원 소모가 줄어들게 된다.
- 스레드 간 통신 시, 전역 변수의 공간 or 동적으로 할당된 공간인 Heap 영역을 이용하여 데이터 주고 받음으로 통신 방법이 간단하다.
- Context Switching시에, 캐시 메모리를 비울 필요가 없기에 비용이 적고 빠르다.
그래서 시스템 처리량이 향상되고 자원 소모가 줄고 자연스럽게 프로그램 응답시간이 단축된다.
단점
- 서로 다른 스레드가 Data, Heap 영역 등을 공유하기에 어떤 스레드가 다른 스레드에서 사용중인 변수나 자료구조에 접근하여 이상한 값을 읽어오거나 수정 가능하다. 자원 공유의 문제가 발생한다.(동기화)
- 하나의 스레드에 문제가 생기면 전체 프로세스에 문제가 생긴다.
- 디버깅이 까다롭다.
멀티 프로세스와 멀티 스레드 (결론)
-
멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고 Context Switching이 빠르지만, 오류가 발생 시 스레드 종료될때 전체 스레드가 종료될 수 있단 점과 동기화의 문제를 갖고 있다.
-
멀티 프로세싱 방식은 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상 수행한다는 장점이 있지만서도 멀티 스레드보다 많은 메모리 공간 차지와 CPU 시간을 점유한다는 단점이 있다.
작업을 동시 수행 한다는 점에서 둘은 같지만 적용해야 하는 시스템에 따라 적/부적합이 구분되겠다.
대상 시스템에 따라 적합한 동작 방식을 선택하자.
Reference