Q.스레드가 공유하는 자원과 독립적인 자원은?
| 공유 | 독립 |
|---|
| 코드 | 스택 |
| 데이터 (전역변수, static) | 레지스터와 프로그램 카운터 |
| 힙 | 스레드 로컬 저장소 |
| 열린 파일과 소켓 | |
핵심은 스택만 따로 갖는다는 점입니다. 함수 호출 흐름이 스레드마다 독립적이어야 하므로 스택은 나눠야 하고, 나머지는 공유해서 생성과 전환이 가볍습니다.
이 구조가 장점이자 위험입니다. 힙과 전역변수를 함께 쓰므로 통신이 쉽지만, 동시에 접근하면 경쟁 조건이 생깁니다. 한 스레드가 잘못된 메모리를 건드리면 프로세스 전체가 죽습니다.
흔한 실수: 힙을 독립 자원으로 답하는 것. 힙은 프로세스 단위로 하나이고, 그래서 한 스레드가 할당한 객체를 다른 스레드가 그대로 씁니다.
Q.사용자 레벨 스레드와 커널 레벨 스레드의 차이는?
커널이 스레드의 존재를 아는지가 다릅니다.
| 항목 | 사용자 레벨 | 커널 레벨 |
|---|
| 관리 주체 | 라이브러리 | 커널 |
| 생성과 전환 비용 | 매우 싸다. 모드 전환이 없다 | 상대적으로 비싸다 |
| 멀티코어 활용 | 어렵다. 커널은 프로세스 하나로 본다 | 가능하다 |
| 하나가 블로킹되면 | 프로세스 전체가 멈춘다 | 그 스레드만 멈춘다 |
두 번째와 네 번째가 결정적입니다. 사용자 레벨만 쓰면 스레드 하나가 파일을 읽는 동안 나머지도 멈춥니다.
현대 운영체제는 대부분 커널 레벨을 쓰고, 그 위에 경량 실행 단위(코루틴, 고루틴, 가상 스레드)를 올리는 방식이 늘고 있습니다. 커널 스레드 몇 개에 수만 개의 논리 흐름을 얹어 두 장점을 합치려는 시도입니다.
흔한 실수: 사용자 레벨을 옛 기술로만 설명하는 것. 지금의 코루틴이 같은 아이디어를 다시 쓰고 있습니다.
Q.스레드풀을 사용하는 이유는?
스레드를 매번 만들고 없애는 비용을 없애고, 동시 실행 수에 상한을 두기 위해서입니다.
| 이유 | 내용 |
|---|
| 생성 비용 제거 | 미리 만들어 두고 재사용한다 |
| 개수 제한 | 요청이 몰려도 스레드가 무한히 늘지 않는다 |
| 자원 보호 | 문맥 교환 폭증과 메모리 고갈을 막는다 |
| 큐잉 | 넘치는 작업을 대기열에 담아 순서대로 처리한다 |
두 번째가 더 중요합니다. 요청마다 스레드를 만들면 동시 접속 2,000에서 실행 흐름이 2,000개가 되고, 커널이 이들을 번갈아 실행하는 비용만으로 CPU 가 소진됩니다.
풀 크기는 작업 성격으로 정합니다.
| 작업 | 크기 기준 |
|---|
| CPU 중심 | 코어 수 안팎 |
| I/O 대기가 긴 작업 | 코어 수보다 크게. 대기 비율만큼 |
흔한 실수: 크면 좋다고 보는 것. CPU 중심 작업에서 스레드를 코어보다 많이 두면 교환 비용만 늘어납니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
운영체제 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.