본문 바로가기
Computer Science/운영체제

[운영체제] ep3) 스레드(thread)

by 클레어몬트 2024. 4. 8.

[컴퓨터 구조] ep5) 스레드 파트를 복습하자

스레드: 실행의 단위

- 하드웨어적 스레드: 하나의 코어가 동시에 처리하는 명령어 단위

- 소프트웨어적 스레드: 하나의 프로그램에서 독립적으로 실행되는 단위

 

https://claremont.tistory.com/entry/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-ep5-CPU-%EC%84%B1%EB%8A%A5-%ED%96%A5%EC%83%81-%EA%B8%B0%EB%B2%95

 

[컴퓨터 구조] ep5) CPU 성능 향상 기법

세계 곳곳의 과학자들과 엔지니어들은 조금이라도 더 빠른 CPU를 만들기 위해 혈색이다 이번 장에서는 CPU 설계 기법과 명령어 처리 기법들에 대해 알아보겠다 ㅇ클럭 "컴퓨터 부품들은 클럭이라

claremont.tistory.com

 

 

오늘 우리가 배울 내용은 소프트웨어적 의미를 가진 스레드이다

ㅁ스레드(thread): 프로세스를 구성하는 디스패칭의 흐름 단위

clone()은 exec()와 비슷한 성질의 함수이다

 

- 스레드도 PCB와 비슷한 TCB(Task/Thread Control Block)를 가진다, PCB가 (자원+실행) 정보라면 멀티스레딩에서의 TCB는 (실행) 정보만을 담는다

자원: memory, Resource Ownership, Utilization, ...

실행: 스케줄링, state, ...

 

- 스레드도 프로세스와 똑같이 5가지 상태(state)를 가진다

Spawn(=New), Ready, Running, Blocked, Finish(=Exit)

※ 기본적으로 스레드의 suspension에는 Swap Out이 없고 나머지는 다 있다

(나머지: 동기화, 주기적인 timing, Parent의 suspend 요청, ...)

스레드 상태 다이어그램도 프로세스와 똑같다!

 

- 스레드도 Processor State Information이 있다

PC 등의 레지스터 값을 담는 스레드 문맥(thread context)이 존재한다

 

- 스레드는 스레드별로 서로 다른 스택(stack)을 가진다

 

- 지역 변수, 정적 변수는 스레드별로 관리한다

 

프로세스의 스레드들은 실행에 필요한 최소한의 정보(PC와 같은 레지스터 값, 스택 등)만을 유지한 채 프로세스 자원을 공유하며 실행된다 → 스레드마다 각기 다른 코드를 실행 가능하다

 

 

 Linux에서는 프로세스와 스레드를 태스크(task)라 총칭한다

다시 말하면, Linux에서는 프로세스와 스레드를 구분 짓지 않는다

Linux와 git의 창시자인 오픈소스의 전설 리누스 토르발스(Linus Torvalds)는 이렇게 말한다 "프로세스와 스레드는 그저 실행의 문맥이다, 프로세스와 스레드를 별개의 것으로 구분할 이유가 없다. 전통적으로는 그렇게 해왔지만, 개인적으로 그것은 역사적인 짐과 같다고 생각한다."

(근데 뭐 굳이 task가 프로세스냐 스레드냐 따진다면 당연히 프로세스에 더 가깝기는 하다)

 

 

 

ㅇ단일 스레드 프로세스: 하나의 스레드로 하나의 프로세스를 실행

실행의 흐름 단위가 하나

 

 

ㅇ멀티프로세스(multiprocess): 여러 단일 스레드 프로세스를 동시에 실행

 

메모리 주소와 PID만 다른 동일한 프로세스 2개(fork 1번)

 

 

ㅇ멀티스레딩(multithreading): 단일 프로세스에서 여러 개의 스레드를 실행

 

 

자원을 공유하기 때문에 메모리를 더 효율적으로 사용할 수 있고 서로 협력과 통신에 유리하다, 하지만 스레드가 공유하는 자원에 문제가 발생할 경우에는 더 큰 문제를 일으킨다

양날의 검

 

 

 

[싱글 스레드 프로세스 vs 멀티 스레드 프로세스]

싱글 스레드 vs 멀티 스레드
모든 ID는 다 PCB에 담겨있다 유의!

 

 

ㅁ멀티스레딩 구현방식 3가지: ULTs, KLTs, Combined

1. ULTs(User-Level Threads): 멀티스레딩을 이용해 프로그램을 작성 by Thread Library

스레드 라이브러리만 있다면 모든 OS에서 실행 가능하다는 장점이 있다

pure User-Level

 

ULTs와 프로세스 상태의 관계 예시

 

 

 

2. KLTs(Kernel-Level Threads): 커널에서 멀티스레딩을 지원 by Kernel

가장 일반적이며 멀티 프로세서 시스템에 적합하다 e.g. Windows

pure Kernel-Level

 

[ULTs vs KLTs]

- 속도 측면에서 ULTs가 더 빠른 경우: 문맥 전환이 빈번하고, 블로킹 작업이 적으며, 단일 프로세서 시스템에서 주로 사용되는 경우

- 속도 측면에서 KLTs가 더 빠른 경우: 멀티프로세서 시스템에서 병렬 처리가 필요하고, 블로킹 작업이 많은 경우

 

 

 

3. Combined(ULTs + KLTs)

불필요한 스레드 생성을 막고 불필요한 스레드 스위칭을 안 하기 위해서 Combined 방식을 사용

커널 레벨 스레드 <= 유저 레벨 스레드

 

 

 

(추가) 스레드:프로세스 비율의 다양한 OS들

 

 

 

그러면 이제 각 운영체제별로 한 번 살펴보자

[Windows]: KLTs + 멀티스레딩 지원

하나의 프로세스에 최소 하나 이상의 스레드

스레드는 디스패치 가능한 단위 -> Ready-Queue에서 프로세스가 줄을 서는 게 아니라 스레드가 줄을 선다

Windows Thread States

 

<대표적인 프로세스 속성>

- PID

- Base Priority: 처음 할당받을 때의 기본 우선순위 (최소 리미트)

- default processor affinity: 프로세스나 스레드가 특정 프로세서(코어)에서 실행되도록 제한하는 기능. 이를 통해 특정 프로세서에 대한 작업을 제어하고, 캐시 효율성을 높이거나 CPU 부하를 관리할 수 있다 (Windows는 멀티 프로세서를 가정하고 만든 시스템이다)

- ouota limits: 시스템 안에 있는 자원들을 이 프로세스가 얼마까지 사용할 수 있는지

- execution time: 모든 스레드들이 실행되는 데 걸리는 시간

- I/O counters: I/O 작업들 몇 번이나 했는지

- VM operation counters: VM 관련 작업을 몇 번이나 했는지

 

<대표적인 스레드 속성>

- TID

- Thread Context

- Dynamic Priority: 동적 우선순위 (Base Priority를 넘지 않는다)

- Base Priority: 처음 할당받을 때의 기본 우선순위 (최소 리미트)

- thread processor affinity: 프로세스 전체가 아닌 개별 스레드 수준에서 특정 프로세서에서만 실행되도록 제한하는 기능 (세밀하게 CPU 자원을 관리하고 최적화 가능)

 

 

 

Solaris란 Sun 마이크로시스템즈(현 오라클이 인수)의 UNIX 기반 OS 이다

[Solaris]: Combined 방식

Process and Threads in Solaris

 

 

Solaris Thread States

 

 

 

[Linux]: 멀티스레딩 제공 x, but 멀티스레딩 같은 느낌

Linux Threads

 

 

Linux Task(Process/Thread) Model

 

 

 

 

 

 

 

 

 

 

참고 및 출처: Operating Systems: Internals and Design Principles(William Stalling), Operating System Concepts(Silberschatz, Abraham), 혼공컴운(강민철)