프로세스는 한 개 이상의 스레드를 갖는다.
스레드: 프로세스에서 실제로 실행되는 흐름의 단위
스레드는 프로세스 안에 존재하므로 프로세스의 메모리 공간을 이용하고, 지역 변수를 저장하는 스택 영역을 할당받는다.
그리고 전역 변수를 저장하는 힙 영역은 다른 스레드와 공유한다.
쓰레드에 대해 설명해주세요.
쓰레드는 프로세스 내에서 실행되는 여러 흐름의 단위입니다.
프로세스 내에서 레지스터와 스택만 따로 할당 받고, Code, Data, Heap 영역은 스레드끼리 공유합니다.
쓰레드의 메모리 공간에 대해 설명해주세요.
쓰레드는 프로세스의 메모리 공간인 힙, 데이터, 코드 영역을 공유하며 레지스터, 스택 영역을 따로 할당받습니다.
그렇기 때문에 쓰레드간 Context Switch는 적은 오버헤드를 갖습니다.
스레드를 여러 개 생성해 스레드들이 각자 다른 작업을 처리하는 것을 의미한다.
멀티 스레드는 스레드 간에 힙, 데이터, 코드 영역을 공유한다.
그래서 콘텍스트 스위칭할 때 오버헤드가 적게 발생하고, IPC를 사용하지 않아도 되어 멀티 프로세스의 단점을 보완할 수 있다.
스레드 간 자원 공유가 프로세스 간 자원 공유보다 시스템 처리 비용이 적고, 프로그램 응답 시간도 단축된다.
하지만 스택 영역을 제외한 메모리 영역을 다른 스레드와 함께 사용하므로, 공유 자원에 대한 동기화가 필수다.
또한, 스레드에 문제가 생기면 프로세스 내 다른 스레드에 영향을 미칠 수 있다.
프로세스 내 공유가 가능한 부분을 제외하고 실행과 관련된 부분을 스레드로 나누어 관리하면 자원의 중복 사용을 피함으로써 낭비를 막을 수 있다.
또한, 하나의 프로세스에서 여러 개의 스레드를 사용하면 작업의 효율을 높일 수 있다.
응답성 향상
한 스레드가 입출력으로 인해 작업이 진행되지 않더라도 다른 스레드가 작업을 계속하여 사용자의 작업 요구에 빨리 응답할 수 있다.
자원 공유
한 프로세스 내에서 독립적인 스레드를 생성하면, 프로세스가 가진 자원을 모든 스레드가 공유하게 되어 작업을 원활하게 진행할 수 있다.
효율성 향상
여러 개의 프로세스를 생성할 필요가 없어, 불필요한 자원의 중복을 막음으로써 시스템의 효율이 향상된다.
다중 CPU 지원
2개 이상의 CPU를 가진 컴퓨터에서 멀티스레드를 사용하면, 다중 CPU가 멀티 스레드를 동시에 처리하여 CPU 사용량이 증가하고, 프로세스의 처리 시간이 단축된다.
멀티스레드의 경우 모든 스레드가 자원을 공유하기 때문에, 한 스레드에 문제가 생기면 전체 프로세스에 영향을 미친다.
반면, 프로세스를 여러 개 만드는 방식의 경우 각 프로세스가 독립적이기 때문에 한 프로세스의 문제가 다른 프로세스로 전달되지 않는다.
그 예로 인터넷 익스플로러와 크롬이 있다.
익스플로러는 멀티스레드를 이용하며, 크롬은 멀티태스킹으로 탭을 구현하였다.
익스플로러는 여러 개의 화면을 동시에 띄웠을 때 그 중 하나에 문제가 생겨 해당 화면을 종료하면, 그 화면만 사라지는 것이 아니라 익스플로러 전체가 종료된다.
이는 각 탭(스레드)가 하나의 프로세스의 데이터를 공유하고 있기 때문이다.
하지만 크롬은 각 화면이 독립적인 프로세스이므로 그 중 하나에 문제가 생겨서 종료해도, 다른 화면에 미치는 영향이 작다.
크롬은 다른 스레드가 영향받는 것을 최소화하기 위해 낭비 요소가 있더라도 멀티스레드 대신 멀티태스킹을 이용한다.
멀티 쓰레딩 프로그래밍에 대해서 설명해주세요.
멀티쓰레딩은 프로세스로 해야하는 작업을 여러 개의 쓰레드로 나누어서 수행하는 것을 말합니다.
쓰레드는 프로세스의 자원을 공유하기 때문에fork()
로 인한 쓰레드 생성은 프로세스 생성보다 빠릅니다. (공유하는 부분을 제외한 부분만 복사하면 되기 때문입니다.)
또한, 커널의 개입 없이 쓰레드간 통신 할 수 있습니다.
하지만 쓰레드 간 자원을 공유하기 때문에 쓰레드가 접근하는 공유 데이터에 대해 동기화 작업을 수행해야 합니다.
멀티 쓰레드 프로그래밍의 장단점을 설명해주세요.
멀티 스레드 프로그래밍은 하나의 프로세스에서 여러 개의 스레드를 만들어 처리하는 프로그래밍 방식입니다.
장점으로는
- 프로세스 내에 있는 모든 스레드들이 프로세스의 자원을 공유하므로 자원 중복에 대한 낭비를 막을 수 있습니다.
- 한 스레드가 입출력으로 인해 작업이 진행되지 않더라도, 다른 스레드가 작업을 이어서 할 수 있습니다.
단점으로는
- 자원을 공유하기 때문에, 한 스레드에 문제가 생기면 전체 스레드에 영향을 미칩니다.
- 공유 자원에 대한 동기화가 필요합니다.
멀티 프로세스 대신 멀티 쓰레드를 사용하는 이유가 뭔가요?
프로세스 내에 있는 모든 스레드들이 프로세스의 자원을 공유하므로, 자원 중복에 대한 낭비를 막을 수 있는 있어 시스템의 효율이 향상되기 때문입니다.
멀티 쓰레드 프로그래밍에서 주의할 점이 있을까요?
자원을 공유하기 떄문에,Thread-safe (스레드 안전)
하게 작성하여, 동시성 이슈가 발생하지 않도록 해야 합니다.
커널과 시스템 콜에서 모드의 구분이 있던 것처럼(커널 모드, 유저 모드) 스레드도 스레드를 관리하는 주체에 따라 구분된다.
사용자 레벨 스레드
사용자가 라이브러리를 이용해 생성 및 관리한다.
커널 레벨 스레드
커널이 스레드를 생성 및 관리한다.
멀티 레벨 스레드 환경에서 사용자 레벨 스레드와 커널 레벨 스레드는 3가지 관계를 맺을 수 있다.
다대일 모델 (사용자 스레드)
커널이 멀티스레드를 지원하지 않을 때 사용하는 방법이다.
사용자 레벨 스레드 n개에 커널 레벨 스레드 1개가 매핑되어 사용자 레벨에서 스레드를 관리한다.
사용자 스레드는 라이브러리가 직접 스케줄링하고, 작업에 필요한 정보를 처리하기 때문에 문백 교환이 필요없다.
하지만, 사용자 스레드는 보안에 취약하다.
하나의 사용자 레벨 스레드에서 시스템 콜을 호출하면, 나머지 사용자 레벨 스레드는 커널 레벨에 접근할 수 없으므로, 멀티 코어의 병렬성을 이용할 수 없다.
일대일 모델 (커널 스레드)
커널이 멀티 스레드를 지원하는 방식이다.
사용자 레벨 스레드 1개에 커널 레벨 스레드 1개가 매핑된다.
하나의 사용자 레벨 스레드에서 시스템 콜을 호출하면, 다른 레벨 스레드가 모두 실행되지 않는 다대일 모델의 단점을 해결한다.
커널의 기능을 사용하므로 보안에 강하고 안정적으로 작동한다.
하지만 사용자 레벨 스레드 수만큼 커널 레벨 스레드가 생성되므로, 성능 저하가 일어날 수 있다. (문맥 교환을 할 때 오버헤드 때문에 느리게 작동한다.)
다대다 모델 (멀티 레벨 스레드)
사용자 레벨 스레드 n개에 커널 레벨 스레드 m개가 매핑된다.
커널 레벨 스레드의 수는 사용자 레벨 스레드의 수 이하다.
빠르게 움직여야 하는 스레드는 사용자 스레드로 작동하고, 안정적으로 움직여야 하는 스레드는 커널 스레드로 작동한다.
다대일 모델과 일대일 모델의 장점을 포함하지만, 구현이 어렵다는 단점이 있다.
사용자 수준 쓰레드와 커널 수준 쓰레드의 차이를 설명해 보세요.
- 사용자 수준 스레드란, 라이브러리를 통해 구현한 스레드를 의미합니다.
스레드와 관련된 모든 행위를 사용자 영역에서 하기 때문에, 커널은 사용자 수준 스레드의 존재를 알지 못하고 스레드 교환에 개입하지 않습니다.- 커널 수준 스레드란, 커널이 직접 생성하고 관리하는 스레드를 의미합니다.
등 스레드에 대한 다양한 정보를 저장한다.
TCB도 스레드가 생성될 때 운영체제에 의해 생성되며, 스레드가 실행되고 삭제될 때 같이 삭제가 이루어진다.
스레드 간의 자원 공유와 동기화도 TCB를 사용하여 관리가 이루어지는데, 이는 동기화 기법을 사용할 때,
TCB에서 해당 스레드의 뮤텍스나 세마포어 정보를 관리하고, 스레드가 해당 자원에 대한 접근 권한을 획득하거나 반납할 때 TCB의 정보를 업데이트하게 된다.
스레드 상태 | 설명 |
---|---|
NEW | 스레드가 생성은 되었으나, 아직 호출되지 않은 상태 |
RUNNABLE | 스레드가 생성을 기다리는 상태로, 실행할 준비가 된 상태 |
BLOCKED | 스레드가 특정 이벤트가 발생하여 대기하는 상태로, CPU를 할당받을 수 없으며 이벤트가 발생하여 다시 RUNNABLE 상태로 전환될 때까지 대기하는 상태이기도 하다. |
TERMINATED | 스레드가 실행되고 완려되며 종료된 상태로, 메모리에서 제거 된다. |
스레드 컨텍스트 스위칭
은 CPU가 현재 실행 중인 스레드의 상태를 저장하고, 다른 스레드의 상태를 복원하여 실행을 전환하는 과정이다.
이는 멀티스레딩 환경에서 필수적인 작업으로, 여러 스레드가 CPU를 번갈아가며 사용하게 한다.
현재 스레드의 상태 저장
CPU는 현재 실행 중인 스레드의 레지스터, 프로그램 카운터, 스택 포인터 등의 상태 정보를 저장한다.
이 정보는 스레드 제어 블록 (TCB)라는 구조체에 저장된다.
다른 스레드의 상태 복원
CPU는 실행할 다른 스레드의 상태 정보를 TCB에서 읽어온다.
레지스터, 프로그램 카운터, 스택 포인터 등을 복원한다.
다른 스레드 실행
CPU는 복원된 상태 정보를 바탕으로 다른 스레드를 실행한다.
컨텍스트 스위칭은 다음과 같은 이유로 오버헤드가 발생할 수 있다.
저장 및 복원 작업
현재 스레드의 상태를 저장하고, 다른 스레드의 상태를 복원하는 작업이 필요하다.
캐시 미스
새로운 스레드가 실행될 때 CPU 캐시가 비효율적으로 사용될 수 있다.
스케줄링
어떤 스레드를 실행할지 결정하는 스케줄링 작업에도 시간이 소요된다.
쓰레드 제어블록(TCB)에 대해 설명해주세요.
쓰레드 제어블록은 프로세스의 PCB처럼 각 스레드마다 운영체제가 문맥 정보를 담고 있는 자료구조입니다.
TCB에는 쓰레드 ID, 쓰레드 우선순위, 스케줄링 정보 등을 저장하고 있습니다.
스레드 안전(thread safe
은 멀티 스레드 환경에서 하나의 변수, 함수, 객체에 스레드 여러개가 동시에 접근해도 문제가 없음을 의미한다.
스레드 안전하지 않은 경우는 var++
의 코드에서도 나타난다.
위의 코드를 실행하는 과정에서 스레드 두 개가 접근하면 잘못된 결과를 초래할 수 있다.
상호배제 (mutual exclusive)
공유 자원에 접근해야 할 때, 뮤텍스 또는 세마포어와 같은 상호배제 기법을 사용해 접근을 통제해야 한다.
원자 연산 (atomic operation)
공유 자원에 접근할 때, 원자 연산
을 이용하거나 원자적으로 정의된 연산을 이용해 연산 도중에 다른 스레드가 접근할 수 없게 한다.
여기서 원자 연산이란, '연산했다'와 '연산 안했다' 두 가지만 존재하는 연산이다.
재진입성 (reenterancy)
특정 함수를 하나의 스레드에서 실행 중일 때, 다른 스레드가 해당 함수를 실행해도 각 스레드에 올바른 결과가 나올 수 있게 해야한다.
스레드 지역 저장소 (thread local storage)
각 스레드에서만 접근할 수 있는 저장소를 사용해서 공유되는 자원을 줄여야 한다.
Thread-Safe 하다는 의미와 그렇게 설계하는 방법을 설명해 주세요.
Thread-safe하다의 의미는, 여러 쓰레드가 동일한 자원에 접근하더라도 동시성 이슈가 발생하지 않는 것을 의미합니다.
Thread-safe하게 설계를 하려면, 기본적으로 불변 객체를 활용하는 것이 Thread-safe하게 설계할 수 있는 방법 중 하나라고 생각합니다.
그 외에 락을 통해 공유 자원에 접근할 스레드를 제한하는 방법이 있습니다.