Search

쓰레드와 동시성

스레드?(Thread)
CPU 활용의 기본 단위
프로세스 내에서 프로그램 명령을 실행하는 기본 단위
스레드ID, 프로그램 카운터, 레지스터 집합(program counter, stack pointer 등), 스택 으로 구성
같은 프로세스에 속한 다른 스레드와 코드, 데이터 섹션, open files 등의 운영체제 자원 공유
스레드의 장점
사용자 응답성
일부 스레드의 처리가 지연되어도, 다른 스레드는 작업을 계속 처리 가능
자원 공유
자원을 공유해서 효율성 증가
동일 주소 공간에서 스레드가 여러 개
커널의 개입을 피할 수 있음
경제성
프로세스의 생성, 컨텍스트 스위치에 비해 효율적
멀티 프로세서 활용
병렬 처리를 통한 성능 향상
단일 스레드(Single Thread)
프로세스 內 제어 스레드 1개 단일 스레드(Single Thread)
1개의 레지스터, 1개의 스택
[장점]
자원을 공용화 하지 않으므로 공용 자원 접근 통제 불필요
Context Switch 작업 불필요
[단점]
다수개의 CPU활용이 불가
멀티 스레드(Multi Thread) ← 이점을 이해해야 한다
프로세스 內 제어 스레드 다수
프로그램을 다수의 실행 단위로 나누어 실행
각각의 스레드가 고유의 레지스터와 스택으로 표현
[장점]
Responsiveness
대응적(응답성) 측면 : 일부가 차단되거나 장시간 작업 수행시에도 계속해서 실행 가능
Resource sharing
자원 공유성 : 프로세스의 자원과 상태를 공유. 효율적인 운영
Economy
경제성 : 자신이 속한 프로세스의 자원을 공유하기 때문에, 스레드를 만들고 context switch를 진행하는 것이 더 경제적
Multi processor
확장성 : 다수개의 코어에서 병렬로 프로세스 실행
멀티 스레드 사용의 예
→ 하나의 스레드일 경우 동시 다발적인 I/O 처리는 불가능
유저 스레드와 커널 스레드 (멀티 스레드의 확장)
유저 스레드
커널의 별도 지원 없이 커널 위에서 동작
(커널은 스레드의 존재를 모른다)
사용자 영역에서 스레드 연산을 수행한다.
사용자 영역에서 스레드 연산을 수행하기 때문에 운영체제에 투명하다.
커널에 의존적이지 않은 형태로 스레드의 기능을 제공하는 라이브러리를 활용하는 방식이 사용자 레벨(User Level) 스레드다.
사용자 영역의 스레드 라이브러리로 구현된다
스레드 라이브러리에 스레드 생성/파괴를 위한, 메시지/데이터 전달을 위한, 스레드 문맥 저장/복구를 위한 코드가 포함
POSIX threads, Win32 threads, Java thread API 등
장점
커널의 관리를 받지 않음
스레드 스위칭에서 커널모드 권한이 필요하지 않음
어느 운영체제에서나 사용 가능(이식성-portability이 높음)
커널 단을 거치지 않고 빠르게 생성 및 유연한 관리 가능
스케줄링 결정이나 동기화를 위해 커널을 호출하지 않기 때문에 인터럽트가 발생할 때 커널 레벨 스레드보다 오버헤드가 적다.
즉, 위의 말은 사용자 영역 스레드에서 행동을 하기에 OS Scheduler의 context switch가 없다(유저레벨 스레드 스케줄러를 이용).
커널은 사용자 레벨 스레드의 존재조차 모르기 때문에 모드 간의 전환이 없고 성능 이득이 발생한다
단점
프로세스에 속한 스레드 중 I/O 작업등에 의해 하나라도 블록이 걸린다면 전체 스레드가 블록된다.(싱글 스레드 커널의 경우)
멀티프로세싱의 이점을 가질 수 없음 (OS가 자동으로 해주는 일이 없다)
시스템 전반에 걸친 스케줄링 우선순위를 지원하지 않는다. (무슨 스레드가 먼저 동작할 지 모른다.)
커널 스레드
운영체제로부터 직접 지원과 관리를 받음
커널 스레드는 가장 가벼운 커널 스케쥴링 단위다.
하나의 프로세스는 적어도 하나의 커널 스레드를 가지게 된다.
커널 영역에서 스레드 연산을 수행하게 된다.
커널이 스레드를 관리하기 때문에 커널에 종속적이다.
프로그래머 요청에 따라 스레드를 생성하고 스케줄링하는 주체가 커널이면 커널 레벨(Kernel Level) 스레드라고 한다.
장점
프로세스 내 스레드들이 병행 수행 가능
동일한 프로세스의 여러 스레드를 서로 다른 프로세스에 예약가능
프로세스의 한 스레드가 차단되면 커널은 다른 스레드를 예약함
단점
커널 모드로의 전환은 프로세스에서 한 스레드에서 다른 스레드로 제어 전환이 필요
context switching 등 오버헤드가 크다
유저 스레드에 비해 수백배 느림
멀티 스레딩 모델 – 다대일 모델
커널 스레드 1개당 사용자 스레드 n개를 의미한다. 즉, 1 : n 방식이다.
이 방식같은 경우에는 커널은 사용자 스레드가 100개가 있어도 전혀 모르기 때문에 사용자 스레드에서 I/O가 하나라도 발생하면 해당 프로세스는 I/O가 풀릴 때 까지 영원히 block된다.
한 번에 하나의 스레드만 커널에 액세스 할 수 있으므로 멀티 스레드는 멀티코어 시스템에서 병렬로 실행할 수 없음
멀티 스레딩 모델 – 일대일 모델
각각의 유저 스레드를 커널 스레드와 맵핑
1:1 방식이기에 병렬성은 좋으나 효율성 면에서 다소 떨어진다.
더 많은 병렬성, 그러나 사용자 수준 스레드 생성시에도 커널 스레드 생성이 필요하다는 단점 → 굳이 커널 스레드가 필요 없어도 생성을 해야합니다. (사용자 수준에서 해결이 가능해도 )
멀티 스레딩 모델 (3) – 다대다 모델 (중요)
많은 유저 레벨 스레드를 더 작거나 같은 수의 스레드로 다중화
커널 스레드 수는 응용 프로그램이나 특정 기계로부터 특정되어짐
개발자(사용자)는 필요한 만큼 많은 유저 스레드 생성 가능
스레드가 봉쇄형 시스템 호출발생시에도 커널은 다른 스레드 수행을 스케쥴 할 수 있음
커널 스레드는 자신에게 할당된 하나의 사용자 스레드가 block되어도, 다른 스레드를 수행 가능 (병행 처리가 가능)
효율적이면서 유연함
멀티 스레딩 모델 (4) – 2단계 모델
다대다 + 일대일
많은 유저 레벨 스레드를 더 작거나 같은 수의 스레드로 다중화
+ 또한 한 유저 스레드가 하나의 커널 스레드에만 맵핑되는 것을 허용
스레드 풀 → 암묵적 스레딩의 한 종류
쓰레드 = 유저의 응답 요청
쓰레드 폭증 시 쓰레드를 무한 생성하게 됨
쓰레드가 메인이 아닐 때에도 다른 부분까지 성능 저하
만약 요청이 폭증할 것 같다면 쓰레드 풀을 증가시켜 놓아야 한다.
스레드 풀(Thread Pool)
지정된 개수의 스레드를 미리 생성해두고 필요시 꺼내어 쓰는 방식
요청이 폭증해도 성능을 유지
대량 작업 처리에서 반드시 고려 필요
스레드 풀(Thread Pool) 장점
급격한 성능저하 방지
동시 사용자수 증가시에도 대응 가능
이전 생성 스레드 재사용 가능(시스템 자원측면에서 장점)
스레드 풀(Thread Pool) 단점
과다 생성시 메모리 측면에서 낭비 발생 가능성
language 레벨의 스레드 풀 → JAVA를 통한 구현 예시
JVM에 의해 생성 및 관리 됨
middleware-level threads
java.util.concurrent.Executors 및 java.util.concurrent.ExecutorService 사용
Amdahl’s Law
Identifies performance gains from adding additional cores to an application that has both serial and parallel components
– S is serial portion – N processing cores – That is, if application is 75% parallel / 25% serial, moving from 1 to 2 cores results in speedup of 1.6 times – As N approaches infinity, speedup approaches 1 / S
Serial portion of an application has disproportionate effect on performance gained by adding additional cores