Multithreading
Server Architecture
서버의 내부
무한루프를 도는 루프가 있다.
request가 도착했을 때 깨어날 수도 있고
일정한 주기로 깨어날 수도 있다.
request queue에 request message가 있으면 이를 따와서 처리하고 결과를 돌려준다
두 가지 패턴이 존재
iterative server
서버가 스스로 request를 받고 처리하는 것
concurrent server
message queue에서 메세지를 따오면 서버가 직접 처리하는 것이 아니라
그 일을 처리하는 woker process를 fork해서 얘가 처리하게 하는 것
그 때 server은 service로부터 자유로워지니까 다시 request queue에서 가져오면 된다
질문
concurrent surver의 부담?
=> 처리할 요청의 수 만큼 프로세스를 생성해야 하기 때문에 부담이 발생할 수 있다.
! 그 해결책이 오늘 배울 멀티쓰레딩☺🌈
Multithreading
Multithreading의 목적
concurrency는 높이면서 Execution Unit을 생성하거나 수행시키는데 드는 부담을 줄임
필요 이유
- 적은 비용으로 Concurrency를 얻기 위해
- Massively Parallel Scientific Programming을 할 때 발생하는 오버헤드를 줄이기 위해
질문
하나의 process는 여러 개의 thread를 갖는데 이 thread는 어떻게 구현될까?
=> stack으로 구현된다
=> multithreading은 여러 개의 stack을 갖게 된다
Thread의 구현을 위해 필요한 자료 구조
Stack
Thread ID
Thread Control Block(TCB)
Thread의 구현
구현 형태
- User-Level 구현
- Kernel-Level 구현
- 혼합 구현
구현 방법
일단 stack을 구현해야 하고 thread control block을 구현해야 한다. 이 때 thread control block은 user-lever에 둔다.
그리고 thread간에 스케쥴링을 위해 유저 레벨에 스케쥴러를 구현한다.
이 함수들을 묶어 라이브러리로 만드는 것이 유저 레벨 스레드 라이브러리 이다.
user-level thread의 문제
- 한 Thread가 Blocking System Call을 호출하는 경우 해당 Process의 모든 Thread가 Block됨
- 운영체제가 Thread에게 직접 Interrupt를 전달할 수 없기 때문에 Preemptive Scheduling을 할 수 없음
장점은 multithreading이 처음 나왔을 때 OS를 고치지 않고도 multithreading을 할 수 있었다는 점
kernel-level로 구현하면
- user-level의 모든 단점을 해결하지만 kernel단의 수행 시간이 증가하면서 추가적인 오버헤드가 발생한다.
혼합 구현(Combined)
- 상당 부분을 user-level이 처리.
- 하지만 인터럽트가 왓을 때 인터럽트를 user level 스케쥴러에게 포워드해서 깨어나야될 스레드에게 넘기는 기법을 더함
- 블로킹 시스템 콜을 하면 스레드를 중단시키고 새로운 커널 스택을 할당하고 유저 프로세스에 붙인다음에 리턴한다
우리는 기본적으로 전통적인 UNIX 프로세스에 익숙하다.
그래서 우리는 메인 함수를 기본으로 해서 일련의 프로그램이 시행된다고 생각
그런데 스레드가 여러개 생긴다면? 그리고 그 스레드가 각각 수행하는 코드들은 어떻게 되는거지?
=> 멀티스레딩이 제공해주는 API를 이해할 필요가 있다.
멀티스레딩의 API
가장 널리 사용되는 것은 파직스 API
POSIX(Portable Operating System Interface)
다양한 UNIX 계열 운영체제들의 API를 표준화하기 위해 IEEE가 정의한 인터페이스
파직스에서 멀티스레딩 관한 부분을 Pthreads라고 한다.
pthread_create() | 생성하는 것.
- 스레드가 수행해야 될 코드가 제공된다.
- 이 코드는 C 프로그램의 함수의 function pointer로 전달된다.
- => thread의 entry pointer은 특정 함수가 된다.
=> 그리고 그 function pointer가 Pthread_create에 제공된다
pthread_exit() | UNIX system call 중 exit과 비슷
- colling thread를 terminate 시키는 것
pthread_join() | thread가 terminate할때까지 기다림
pthread_yield() | non preemtive 스케쥴을 포기할 때 사용
스레드의 생성과 소멸
일단 process가 수행될 때, 우리가 UNIX의 conventional한 process model을 따른다.
=> 기본적으로 process는 한 개의 main thread가 존재한다
그런데 이 main thread는 다른 process를 스폰할 수 있다. pthread_create()를 이용해서
=> 이 경우 thread가 두개가 된다.
thread 1은 수행하다가 어떤 이유에서인지 CPU를 포기하고 싶다 => pthread_yield
=> yield된건 wating으로 가거나 ready로 가거나...
언젠가 다시 ready상태가 돼서 수행을 하고..
수행을 마치게 되면 exit을 통해 종료된다.
Process
Design time | 설계의 결과로 독립적으로 수행이 가능한 entity가 나온다
Run time
용어 정리
Process
- 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램
- 메모리에 올라와 실행되고 있는 프로그램의 인스턴스
- 운영체제로부터 자원을 할당받는 작업의 단위 (CPU 시간, 주소 공간, Code, Data, Stack, Heap의 구조로 되어 있는 메모리 영역)
Thread - 프로세스 내에서 실행되는 흐름의 단위
- 프로세스의 특정한 수행 경로
- 프로세스가 할당받은 자원을 이용하는 실행 단위
Task - design time process를 task라고 부름.
'👨💻 CS지식' 카테고리의 다른 글
[ KOCW 운영체제와 정보기술의 원리 | 반효경 ] CPU 스케쥴링 (0) | 2022.08.19 |
---|---|
[ SNU 강의 ] CPU Scheduling | 쉽게 배우는 운영체제 8,9주차 (0) | 2022.08.11 |
[ SNU 강의 ] 운영체제의 기초 | 쉽게 배우는 운영체제 6주차 (0) | 2022.07.12 |
[ SNU 강의 ] 운영체제의 기초 | 쉽게 배우는 운영체제 5주차 (0) | 2022.07.11 |
📢 공지 (0) | 2022.07.07 |