스레드의 장점
1. 응답성
- 프로세스의 일부가 막혀도 실행될 수 있으며, 이는 유저 인터페이스에서 중요하다.
- 예를 들어, 사용자 인터페이스 스레드와 백그라운드 작업 스레드를 분리하여 사용자가 프로그램의 응답성을 유지사면서 긴 작업을 처리할 수 있다.
2. 자원 공유
- 스레드는 프로세스의 자원을 공유하므로 메모리 공유나 message passing이 더 쉽다.
- 스레드는 프로세스의 주소 공간을 공유하므로 변수 등의 데이터를 효율적으로 공유하여 작업을 처리할 수 있다.
3. 경제성
- 스레드는 프로세스 내에서 생성되는 것이므로 프로세스를 만드는 것보보다 메모리 및 자원 사용 측면에서 경제적이다.
- context switching 보다 thread switching이 overhead가 더 적다.
4. 규모성
- 스레드 기반 프로그램은 더 많은 작업을 동시에 수행하는데 더 적합하므로 시스템 규모를 확장하기 용이하다.
- 프로세스가 멀티코어 아키텍처의 이점을 활용할 수 있다.
대부분의 커널들은 멀티 쓰레드를 사용한다.
Parallelism & Concurrency
Parallelism(병렬성) - 두 개 이상의 작업을 동시에 처리하는 것
Concurrency(동시성) - 두 개 이상의 작업을 수행하는 것
따라서 Parallelism하면 Concurrency하지만 Concurrency하다고 Parallelism한 것은 아니다.
Parallelism은 실제로 여러 작업이 동시에 실행되어 속도를 높이는 것을 의미하며 Concurrency는 작업들이 동시 진행되는 것처럼 보이는 것처럼 만들어 프로그램의 응답성과 유연성을 높이는데 목적이 있다.
Data parallelism: 데이터 집합을 나누어 나누어진 데이터를 대상으로 같은 작업을 동시에 수행하는 것
Task parallelism: 같은 데이터를 가지고 다른 작업을 동시에 수행하는 것
Data parallelism은 동일한 작업을 다수의 데이터에 적용하여 병렬화하는 전략으로, 데이터를 나누어 각각에 작업을 수행한다. Task parallelism은 서로 다른 작업들을 동시에 실행하여 병렬화하는 전략으로, 각 작업이 독립적으로 실행된다.
Amdahl’s law
- 프로세스의 모든 부분을 parallel 하게 처리하는 것은 거의 불가능하기 때문에 일부는 serial하게 처리하고 일부는 parallel하게 처리한다면 위와 같은 공식이 나온다(S는 serial 비율, N은 프로세싱 코어 수)
- 프로세스의 serial 부분이 코어를 추가하여 얻는 성능에 불균형적인 영향을 미친다.
User and kernel thread
유저 쓰레드와 커널 쓰레드는 다중 스레딩 환경에서 프로그램의 실행을 병렬로 처리하기 위해 사용되는 개념이다.
유저 스레드(User Thread)
유저 스레드는 응용 프로그램에서 직접 관리되는 스레드이다. 프로그래머가 직접 스레드의 생성, 관리, 스케줄링을 조작한다. 유저 스레드는 운영체제의 스케줄링을 무시하고, 응용 프로그램 내에서만 동작하므로 스레드 전환 등이 상대적으로 빠르다. 하지만 유저 스레드는 운영체제 커널에 의해 직접 관리되지 않기 때문에, 스레드가 블록되거나 I/O 작업을 수행할 때 다른 스레드가 대기하지 않으면 멀티코어 환경에서의 병렬 처리 효율이 떨어질 수 있다.
커널 스레드(Kernel Thread)
커널 스레드는 운영체제 커널에 의해 관리되는 스레드이다. 운영체제에서 스레드의 생성, 스케줄링, 동기화 등을 직접 처리한다. 커널 스레드는 다른 스레드가 블록되거나 I/O 작업을 수행할 때 대기하지 않고 다른 스레드로 전환될 수 있으므로 다중코어 환경에서도 효율적인 병렬 처리가 가능하다. 하지만 커널 스레드의 관리가 운영체제에 의해 이루어지므로 스레드 전환 등의 오버헤드가 크고, 스레드 생성과 관리에 비용이 발생할 수 있다.
유저 스레드와 커널 스레드의 매핑 방식에는 여러가지가 있다.
1. Many to one
유저 스레드가 많이 생성되어도 실제로 실행되는 스레드 수는 제한되는 방식이다. 이 방식은 유저 스레드의 관리가 쉽고 빠르지만, 멀티 코어 환경에서의 병렬 처리 효율성이 떨어질 수 있다.
2. One to one
각 유저 스레드를 커널 스레드에 직접 매핑하는 방식으로 User level thread의 생성이 kernel thread를 생성한다.
유저 스레드마다 별도의 커널 스레드를 할당하므로 병렬 처리 효율성이 높지만 스레드 수가 많으면 시스템 성능에 부담이 될 수 있다.
3. Many to many
많은 유저 스레드를 여러 커널 스레드에 매핑하는 방식으로, 병렬 처리 효율성을 높이면서도 스레드 관리의 부담을 줄일 수 있다.
유저 스레드와 커널 스레드의 매핑은 프로그래밍 언어, 운영체제, 스레드 라이브러리 등에 따라 다르게 구현될 수 있다.
Pthread
pthread는 'POSIX Threads'의 줄임말로, 다중 스레딩을 지원하는 C 및 C++ 프로그래밍에서 사용되는 스레드 라이브러리이다.
pthread의 주요 기능에는 '스레드 생성 및 종료', '스레드 동기화', '스레드 스케줄링', '스레드 취소' '스레드 로컬 스토리지' 등이 있다.
Implicit Threading
Implicit Threading은 프로그램의 병렬 처리를 개발자가 관리하는 대신, 컴파일러나 런타임 시스템이 자동으로 처리함으로써 스레드의 생성과 관리를 더 쉽게 해주는 기술이다. Thread pool, Fork-join, openMP 등이 이에 해당한다.
1. Thread pool
정해진 개수의 thread를 만들어놓고 그 thread에 task를 줘서 처리하게 하는 방식이다. 이 방식은 스레드 생성 및 소멸을 최소화하여 자원을 효율적으로 사용한다.
- Task와 thread 관리에 용이함
2. Fork-Join parallelism
큰 작업을 작은 하위 작업으로 분할하고 이를 스레드에 분배하여 실행하는 병렬 프로그래밍 기술이다. fork 단계는 큰 작업을 작은 덩어리로 분할하는 것이고, join 단계는 작은 작업의 결과를 결합하여 최종 결과를 생성해낸다. 이 방식은 Pthread 보다 high level API라 스레딩이 좀더 쉽다.
3. OpenMP
OpenMP는 다중 코어 프로세서를 위한 병렬 프로그래밍 API이다. 코드의 한 부분에 #pragma omp를 써주면 컴파일러가 알아서 pallerize 해주게 된다.
병렬 루프, 섹션, 작업 및 기타 구조를 지원한다.
Threading issues
멀티 스레드를 사용할 때 스레드 간의 충돌이나 동기화 문제 등 다양한 문제들이 발생할 수 있다.
1. fork() 함수 호출 시
fork()가 호출되면 새로운 프로세스가 생성되면서 기존 프로세스의 메모리 공간이 복사된다. 이 때, 프로세스의 메모리 공간에는 모든 스레드의 상태와 정보도 함께 복사된다. 이로 인해 기존 프로세스와 생성된 프로세스 간에 동기화 문제와 자원 공유 문제가 발생할 수 있다.
2. Signal handling
interrupt 등의 시그널이 발생했을 때, 모든 스레드에 시그널을 보내는 것이 아니라 필요한 스레드에게만 시그널을 보낼 수 있어야 한다. 이를 위해 'pthread_kill(pthread_t tid, int signal)' 함수를 사용한다. 'tid'는 시그널을 받을 스레드의 식별자이며, 'signal'은 보낼 시그널을 나타낸다.
Thread cancellation
스레드 취소는 멀티 스레딩 환경에서 실행 중인 스레드를 중단하거나 종료하는 프로세스를 가리킨다. 스레드 취소에는 두 가지 주요 방법이 있다.
1. Asynchronous Cancellation (비동기 취소)
비동기 취소는 어떤 다른 스레드가 대상 스레드를 즉시 중단하도록 요청하는 방식이다. 이는 강제로 스레드를 중단하므로 자원 누수 및 데이터 무결성 문제가 발생할 수 있다.
2. Deferred Cancellation (지연 취소)
지연 취소는 대상 스레드가 '취소 가능한' 상태인지를 확인하고 체크 포인트를 두어 그 시점에만 중단될 수 있게 하는 방식이다. 이는 대상 스레드가 안전한 상태에서 중단되도록 하여 자원 누수를 방지하고 무결성을 보장할 수 있다.
(cancellation point를 두고 그 시점에만 cancel 될 수 있게 – 스레드가 작업중에 cancel하면 오류 날 수도 있으므로)
disabled되있으면 cancel 안되고 enable 되있어야지만 cancel됨
보통 disabled일 때는 취소할 수 없게 하고, enable일 때만 취소될 수 있게 한다.
Thread local storage(TLS)
TLS는 각 스레드마다 독립적인 저장 공간을 갖게하는 방식이다. 이를 통해 여러 스레드가 동시에 같은 전역 변수를 사용하는 경우에 발생할 수 있는 race condition을 제거할 수 있다. TLS는 주로 스레드 별 로그인 정보, 세션 정보, 설정 등을 저장하는데 활용되며, 스레드가 사라지기 전에는 계속 사용될 수 있다.
'학교공부 > 운영체제' 카테고리의 다른 글
[운영체제] File-System Internals (0) | 2023.06.06 |
---|---|
[운영체제] File system implementation (0) | 2023.06.06 |
[운영체제] File system interface (0) | 2023.06.04 |
[운영체제] Main Memory (0) | 2023.05.11 |
Exercise 3. Process Synchronization (0) | 2023.04.24 |