1. Process and Thread
1) Process and Thread
(1) Process
- 실행중인 프로그램(프로그램의 인스턴스)
- 일련의 명령이 실행되는 것을 특징으로 하는 활동 단위 및 관련 시스템 자원 집합
(2) Two characteristics
- The unit of resource ownership(자원 소유권의 단위)
- 프로세스에 메인 메모리, I/O 채널, I/O 장치 및 파일과 같은 리소스의 제어 또는 소유권을 할당할 수 있다.
- The unit of scheduling / execution(스케줄링/실행 단위)
- 프로세스는 실행 상태(Running, Ready 등)와 priority(우선순위)를 가지며 OS에 의해 예약된 엔티티이다.
지금까지는 프로세스에 단일 실행 시퀀스가 있다고 가정했음
- 실행 단위는 일반적으로 스레드(또는 lightweight process)라고 하며, 리소스 소유권 단위는 일반적으로 프로세스(또는 task)라고 한다.
2) Multithreading
- 모든 최신 OS는 프로세스에 여러 스레드를 포함할 수 있는 기능을 제공한다.
- 대부분의 소프트웨어 애플리케이션은 멀티 스레드이다.
- Multithreading
- 단일 프로세스 내에서 여러 동시 실행 경로를 지원하는 OS 기능
- 프로세스 내에 하나 이상의 스레드가 있을 수 있음
3) Concurrency
- 멀티스레드 프로세스는 여러 프로세스를 사용하는 오버헤드 없이 동시성을 달성한다.
- Concurrency(동시성)
- concurrency system은 모든 작업이 진행되도록 허용하여 둘 이상의 작업을 지원한다.
- concurrency와 parallelism(병렬성)의 차이
- Parallelism(병렬화) : parallel system은 두 개 이상의 작업을 동시에 수행할 수 있다.
- 따라서 병렬화 없이 동시성을 갖는 것이 가능
4) Multithreading Example
- 단일 프로세서에서 멀티프로그래밍은 여러 프로세스 내에서 여러 스레드의 interleaving을 가능하게 한다.
2. Motivation
1) Motivation
- 응용 프로그램에는 여러 task가 있으며 다른 task가 blocking(차단)되지 않고 계속 진행되도록 허용하는 것이 좋음
- 예시) 여러 개의 클라이언트가 동시에 있는 busy web server
- Traditional single-threaded process(기존의 단일 스레드 프로세스)
- 한 번에 하나의 클라이언트만 서비스할 수 있음
- 클라이언트가 요청을 위해 매우 오랜 시간을 기다려야 할 수 있음
- Multi-processing soluction
- 서버는 요청을 수신할 때 요청을 처리하는 새 프로세스를 만듦
- Multi-threading soluction
- 요청이 이루어지면 서버는 다른 프로세스를 생성하는 대신 요청을 처리할 새 스레드를 생서앟고 추가 요청 수신을 재개한다.
- Traditional single-threaded process(기존의 단일 스레드 프로세스)
(1) Web Server 예시 코드
- 여러 개의 동시 요청을 처리하는 웹 서버
// Single-thread, Single-process
void main(){
…
while(1) {
int sock = accept();
// It would be able to service only one client at a time
// It may be a lengthy operation
}
}
// Single-thread, Multi-process
void main(){
…
while(1) {
int sock = accept();
if ((pid = fork()) == 0 ) {
// A child process services the requests
}
}
}
// Multi-thread
void *mythread(void){
…
}
void main(){
…
while(1) {
int sock = accept();
create_thread(mythread);
// child thread handles the requests
}
}
(2) Multithreading
- 프로세스당 단일 실행 스레드에 대한 기존 접근 방식
- UNIX는 여러 프로세스를 지원하지만 프로세스당 하나의 스레드만 지원
- JVM은 여러 스레드가 있는 하나의 프로세스 시스템의 예이다.
- 최신 OS는 일반적으로 멀티스레드이다.
3. Benefits
1) Benefits : Faster response
- Responsiveness(반응성)
- 응용 프로그램은 프로그램의 일부가 실행 중인 경우에도 프로그램을 계속 실행할 수 있음
- I/O와 computation이 중복될 수 있음
- 예시) RPC(Remote Procedure Call)
- 단일 스레드 : 프로그램은 각 서버의 응답을 차례로 기다려야 한다.
- 멀티 스레드 : 두 응답을 동시에 기다림
RPC(Remote Procedure Call) : 서로 다른 컴퓨터에서 실행될 수 있는 두 프로그램이 프로시저 call/return 구문 및 semantics(의미론)을 사용하여 상호 작용하는 시스템 SW 기술
2) Benefits : Creation/communcation cost
- Economy of time
- 전체 PCB를 새로 작성할 필요 없음
- 전환이 프로세스보다 빠름
- Resoure sharing(자원 공유)
- 프로세스 간의 통신에는 보호를 제공하기 위한 커널의 개입과 통신에 필요한 메커니즘이 필요
- 스레드는 공유 메모리와 같은 기술을 통해서만 리소스를 공유할 수 있음
- 이러한 기술은 프로그래머에 의해 명시적으로 배열되어야 함
- 예) int fd = shm_open(name, ..);
- 메모리에서 동일한 데이터를 읽고 쓰는 방식으로 스레드 공동 작업이 가능하다.
3) Benefits : Parallel Processing
- Scalability on multi-core architecture(멀티코어 아키텍처의 확장성)
- 멀티코어 아키텍처에서는 멀티스레드의 이점이 훨씬 더 클 수 있음
- 여러 코어에서 동일한 애플리케이션 실행 가능
- 프로세스를 여러 CPU에서 실행할 수 있음(parallelism)
4. Multithreading
1) Multithreading on Multicore
- 멀티코어 시스템에서 멀티스레드 애플리케이션의 성능 확인
- 속도 향상의 개념은 Amdahl의 법칙에 의해 확립됨
- 16개의 프로세서가 있는 시스템에서 행렬 곱셈 및 FFT(Fast Fourier Transfrom) 계산
- 프로그래밍 문제
- Identifying task(작업 식별) : 작업은 서로 독립적이므로 병렬로 실행할 수 있음
- Balance : 프로그래머는 또한 작업이 동일한 가치의 동일한 작업을 수행하는지 확인해야 함
- Data dependecny(데이터 종속성) : 작업에 의해 액세스되는 데이터에서 두 개 이상의 작업 간의 종속성을 검사해야 한다. 한 작업이 다른 작업의 데이터에 의존하는 경우 프로그래머는 작업 실행이 데이터 종속성을 수용하도록 동기화되어야 함
5. Multithreaded Process Model
1) Mutithreaded Process Model
- 먼저 각 스레드에 대해 별도의 스택이 필요
- 각 스레드에는 고유한 실행 스택(User/Kernel)이 있음
- Thread Control Block(TCB)
- 레지스터 값, 기타 스레드 관련 스케줄링 및 상태 정보 및 스택을 포함하는 각 스레드에 대해 별도의 스레드 관련 control block이 필요
(1) Thread Creation
- 기존 프로세스에서 새 스레드를 생성하는 시간이 새 프로세스를 생성하는 시간보다 훨씬 적음
- 프로세스 간에 전환하는 것보다 동일한 프로세스 내에서 두 스레드 간에 전환하하는 것이 성능이 더 좋음
(2) Multithreading Models
- 스레드 구현에는 두 가지 광범위한 범주가 있다
- ULT(User-level thread)
- KLT(Kernel-level thread)
- 결합된 방법
6. Implementation of Threads
1) User Level Thread
- 모든 스레드 관리는 애플리케이션에 의해 수행됨
- 스레드 라이브러리를 사용하여 멀티스레드 가능
- 스레드 라이브러리에는 스레드 생성 및 삭제, 스레드 간 메시지 및 데이터 전달, 스레드 스케줄링, 그리고 스레드 컨텍스트 저장 및 복원을 위한 코드가 포함되어 있음
- 프로시저 콜에 의해 control이 전달
- 스레드 간 전환에는 다음이 수반됨
- 라이브러리가 라이브러리의 TCB에 저장 또는 로드
- 라이브러리에서 실행할 새 스레드 선택
- 하지만 커널은 관여하지 않음
- 예시
- 기존 UNIX 시스템과 마찬가지로 이전 버전의 Linux 커널은 멀티스레딩을 지원하지 않았다
- 대신 user-level 라이브러리 함수 집합을 사용하여 애플리케이션을 작성해야 했다.
- java 초기 버전의 green thread
(1) 장점
- 스레드 관리는 스레드 라이브러리가 User space에서 수행하므로 효율적
- ULT는 모든 OS에서 실행이 가능
- 기본 OS는 스케줄러를 중단하지 않고 애플리케이션에 맞게 조정 가능
(2) 제한 사항
- 그러나 이러한 접근 방식은 스레드의 주요 이점을 제거한다.
- 커널은 한 번에 하나의 커널 스레드만 스케줄링할 수 있기 때문에 병렬 처리를 하지 않음
- 스레드가 blocking system call을 수행하면 전체 프로세스가 blocking됨
(3) 해결책
- blocking system call을 jacketing이라는 non-blocking system call로 변환한다.
2) Kernel Level Thread
- pure KLT에서 스레드 관리의 모든 작업은 커널에 의해 수행됨
- 커널은 프로세스 내의 개별 스레드에 대한 컨텍스트 정보를 유지
- 응용 프로그램 수준에 스레드 관리 코드가 없음
- 커널 스케줄링된 엔티티 1개당 스레드 1개
- OS-managed thread를 kernel-level thread라고 함
(1) 장점
- 멀티프로세서에서 여러 스레드를 병렬로 실행할 수 있음
- 스레드가 blocking system call을 할 때 다른 스레드가 실행되도록 허용하여 더 많은 동시성을 제공
(2) 제한사항
- 동일한 프로세스 내에서 한 스레드에서 다른 스레드로 제어를 전송하려면 커널로 모드 전환이 필요
- 세부적인 동시성의 경우 커널 수준 스레드는 여전히 오베해드가 너무 큼
- ULT와 KLT 간의 차이가 크기 순 이상인 경우
Null Fork : null procedure를 실행하는 프로세스/프로시저를 생성하고 완료하는 시간
Signal Wait : 프로세스/thread가 대기 중인 프로세스/thread에 신호를 보낸 후 조건에 따라 대기하는 시간
3) Combined
- 일부 OS는 결합된 ULT/KLT를 제공
- 스레드 생성은 사용자 공간에서 수행됨
- 단일 애플리케이션의 여러 ULT가 일부(더 작거나 같은) KLT에 매핑됨
- 프로그래머는 KLT의 수를 조정할 수 잇음
- Solaris는 이 결합된 접근 방식을 사용하는 OS의 좋은 예
4) Kernel- vs User-level Threads
- Kernel-level thread
- OS와 통합
- 생성, 조작, 동기화가 느림
- User-level thread
- 신속한 생성, 조작 동기화
- OS와 통합되지 않음
- 커널과 사용자 수준 스레드 간의 차이점을 이해하는 것이 중요!!!
- 프로그래밍의 정확성, 성능을 위해
7. Thread API
1) Thread API
- POSIX(UNIX 기반 휴대용 운영 체제)는 스레드 API에 대한 표준을 포함하는 IEEE API 표준이다.
- POSIX 스레드 표준을 구현하는 라이브러리는 종종 Pthread로 불림
- Pthread는 Linux 및 Solaris와 같은 UNIX와 유사한 POSIX 시스템에서 가장 일반적으로 사용되지만 마이크로스프트 윈도우즈 구현도 존재
2) Posix Threads(Pthreads) Interface
- Pthreads : 스레드를 조작하는 최대 60개의 함수를 위한 표준 인터페이스
- 기본 pthread 함수
pthread_create – create child thread
pthread_exit – thread termination
pthread_join – wait for thread termination
pthread_self – return the calling thread ID
phtread_mutex_lock – lock critical section
pthread_mutex_unlock – unlock critical section
pthread_cond_wait – wait for a condition signal
phtread_cond_signal – wake up one waiting thread
(1) Creating Threads
- 스레드는 pthread-create를 호출하여 다른 스레드를 만듦
- pthread_create 함수는 새 스레드를 만들고 새 스레드의 컨텍스트에서 arg의 입력 인수를 사용하여 스레드 루틴 f를 실행
- attr 인수를 사용하여 기본 특성을 변경할 수 있다.
- Scheduling priority 등...
- pthred_create가 반환되는 경우 인수 tid에는 새로 생성된 스레드의 ID가 포함됨
#include <pthread.h>
typedef void *(func)(void *);
int pthread_create(pthread_t *tid, pthread_attr_t *attr, func *f, void *arg);
Returns: 0 if OK, nonzero on error
(2) Terminating Threads
- pthread_self() 함수는 호출 스레드의 ID를 반환
#include <pthread.h>
pthread_t pthread_self(void);
Returns: thread ID of caller
- 스레드는 다음 방법 중 하나로 끝남
- 스레드 루틴이 돌아오면 스레드가 암시적으로 종료
- 스레드는 pthread_exit를 호출하여 명시적으로 종료
#include <pthread.h>
void pthread_exit(void *thread_return);
Never returns
(3) Reaping Terminated Threads
- 스레드는 pthread_join을 호출하여 다른 스레드가 종료될 때까지 기다림
- pthread_join함수는 스레드 tid가 종료될 때까지 차단한 다음 종료된 스레드가 보유한 메모리 리소스를 가져옴
#include <pthread.h>
int pthread_join(pthread_t tid, void **thread_return);
Returns: 0 if OK, nonzero on error
3) Thread API 예시
(1) 예시 1
(2) 예시 2 : gcc thread.c -lpthread
<결과>
<분석>
(3) Race Condition
Race Condition : 두 개 이상의 프로세스가 공통 자원을 병행적으로(concurrently) 읽거나 쓰는 동작을 할 때, 공용 데이터에 대한 접근이 어떤 순서에 따라 이루어졌는지에 따라 그 실행 결과가 같지 않고 달라지는 상황을 말함
8. Thread Synchronization
1) Thread Synchronization(스레드 동기화)
- 스레드는 멀티스레드 프로그램에서 상호 작동한다.
- 공유 리소스에 대한 액세스
- 스레드가 공유 리소스에 동시에 액세스하면 어떻게 될까?
- 부정확한 결과로 이어짐
- race condition이라고 불림
- 스레드 동기화 : 정확성을 위해 공유 리소스 또는 해당 실행을 사용하는 스레드를 조정하는 방법
2) 스레드 동기화 목표
- cooperating(협력) 동기화가 올바르게 작동하는지 확인한다.
- 5장, 6장에서 더 배
'오퍼레이팅 시스템' 카테고리의 다른 글
오퍼레이팅 시스템 : Synchronization Ⅱ (1) | 2023.05.08 |
---|---|
오퍼레이팅 시스템 : Synchronization 1 (0) | 2023.05.07 |
오퍼레이팅 시스템 : Processor Scheduling Ⅱ (0) | 2023.04.15 |
오퍼레이팅 시스템 : Processor Scheduling Ⅰ (0) | 2023.04.08 |
오퍼레이팅 시스템 : Process Description and Control Ⅱ (0) | 2023.04.08 |