Multi Programming
배치시스템에서는 OS가 여러 프로세스를 동시에 돌아가는 것처럼 관리
Multi Processing
단일 프로그램이 동작할 때 싱글·멀티패스 프로그램이 여러 프로세스를 사용하는 것, 마치 부모 프로세스가 fork를 통해 자식 프로세스를 만드는 행위
Multi Tasking
큰 OS에선 프로세스로 명칭하나, 라즈베리파이같은 작은 OS에서는 프로세스를 더 작은 단위인 Task 혹은 Thread라 부름.
Multi Processing과 같으며 명칭의 차이
프로세스를 복사해서 여러 프로세스를 운영체제가 관리하는 것은 무겁다
프로세스는 PCB정보를 가진다
메모리 주소공간, OS 자원(프로세스가 열어놓은 파일 주소, 사용하고 있는 I/O 장치 리스트, 프로세스가 어떤 권한으로 열렸는지 등), 실행상태 및 레지스터 사용
새로운 프로세스를 만드는 비용 및 프로세스 간의 통신(IPC) 또한 OS의 부담이 많이 듦
싱글쓰레드 프로세스
왼쪽처럼 하나의 프로세스에 싱글패스로 동작
멀티쓰레드 프로세스
오른쪽처럼 한 프로세스에서 두 개의 쓰레드로 나누어 비동기적으로 처리
다양한 운영체제의 멀티쓰레드
- POSIX기반 OS에서는 쓰레드 생성을 pthread_create(), 쓰레드의 대기를 pthread_join()으로 한다
- 아두이노에서도 멀티 쓰레드(태스크)를 지원하는데 xTaskCreate()로 태스크를 정의하고 vTaskStartScheduler()를 통해 여러개의 태스크들을 실행
싱글코어
Concurrent하게 1, 2, 3, 4, 1, 2, 3, 4 여러개가 동시에 동작하는 것처럼 처리
멀티코어
쓰레드1~4가 들어오면 같은 시간에 코어1 코어2가 1, 2 / 3, 4로 병렬 처리
Data Parallelism
데이터가 나눠서 처리가 된다는 전제(데이터가 서로 dependancy가 없음)하에 데이터를 분배해 각각의 코어에 분배
Task Parallelism
여러 개의 Task를 각각의 코어가 분배받아서 처리
Pthreads(POSIX기반의 쓰레드)
Task Parallelism (쓰레드로 나누어 처리)
OpenMP, OpenMPI, SIMD, CUDA, OpenCL
Data Parallelism (데이터가 서로 독립적이어서 나눔)
ex) RGB 데이터는 서로 독립적이기 때문에 따로나눠서 각각을 따로 처리 후 마지막에 합쳐서 렌더링
OS에서 쓰레드를 개발하는 과정이 힘들고 어렵기에 유저레벨인 라이브러리로 쓰레드 기능을 제공
유저레벨 쓰레드의 단점을 보완하기 위해 커널이 쓰레드와 프로세스를 모두 관리
Many-to-One
N대 1로 커널하나가 여러 쓰레드를 관리하는 유저레벨 쓰레드
One-to-One
1대 1로 커널에서 여러개의 쓰레드를 1:1로 관리하는 커널레벨 쓰레드
Many-to-Many, Two-level
만들어보니 복잡하고 의미없음 잘 안쓰는 방식
만일 Multi Threading으로 동작하는 프로세스가?
exec한다면?
현재 프로세스에 몇 개의 쓰레드가 있던 간에 싹다 밀어버리고 새로운 프로세스를 하나의 쓰레드로 실행
fork한다면?
POSIX의 PThread는 fork를 부른 쓰레드만 있는 프로세스를 복사, 일부 UNIX International Standard에서는 실행중인 모든 쓰레드가 다 있는 프로세스를 복사
이런 복잡한 과정들은 운영체제마다 처리하는 방식이 다르고 복잡해서 사실 개발자들은 Multi Threading이 적용된 프로세스에 한해서 아예 fork하지 않는 것이 불문율. 차라리 fork를 하고 생겨난 자식프로세스를 Multi Threading하는 것은 상관없다.
Pthreads
POSIX 기반의 threads개념으로 쓰레드 열기(create), 닫기(close), 기다리기(join)로 나뉨
Window
CrateThread와 ExitThread 두 개로 간략화
Java
Thread class를 상속 후 run()함수를 오버라이드하거나 runnable이라는 인터페이스를 implements 후 상세히 구현하는 방법