Foundry
운영체제
기초
핵심

스레드 (Thread)

프로세스 내 실행 단위, 메모리 공유

스레드 (Thread)

스레드란?

프로세스 내의 실행 흐름 단위. 같은 프로세스의 메모리를 공유.

공유 vs 독립

공유 자원독립 자원
코드 영역스택
데이터 영역PC (Program Counter)
힙 영역레지스터
파일 디스크립터스레드 ID

사용자 스레드 vs 커널 스레드

구분사용자 스레드커널 스레드
관리 주체라이브러리OS 커널
전환 속도빠름느림 (시스템 콜)
블로킹하나 블록 → 전체 블록독립적

동기화 문제

스레드 A 는 잔액에 100을 더하고, 스레드 B 는 50을 뺍니다.

순서동작잔액
1A 가 읽는다1000
2B 가 읽는다1000. 아직 A 가 쓰지 않았다
3A 가 쓴다1100
4B 가 쓴다950. A 의 변경이 사라졌다
Race Condition 발생. 뮤텍스/세마포어로 해결.

실무 포인트

  • Java: Thread, ExecutorService (스레드풀)
  • Python: GIL 때문에 멀티스레딩 CPU 바운드에 불리
  • Go: goroutine (경량 스레드, M:N 모델)
면접에서 이렇게 나옵니다

Q.스레드가 공유하는 자원과 독립적인 자원은?

공유독립
코드스택
데이터 (전역변수, static)레지스터와 프로그램 카운터
스레드 로컬 저장소
열린 파일과 소켓

핵심은 스택만 따로 갖는다는 점입니다. 함수 호출 흐름이 스레드마다 독립적이어야 하므로 스택은 나눠야 하고, 나머지는 공유해서 생성과 전환이 가볍습니다.

이 구조가 장점이자 위험입니다. 힙과 전역변수를 함께 쓰므로 통신이 쉽지만, 동시에 접근하면 경쟁 조건이 생깁니다. 한 스레드가 잘못된 메모리를 건드리면 프로세스 전체가 죽습니다.

흔한 실수: 힙을 독립 자원으로 답하는 것. 힙은 프로세스 단위로 하나이고, 그래서 한 스레드가 할당한 객체를 다른 스레드가 그대로 씁니다.

Q.사용자 레벨 스레드와 커널 레벨 스레드의 차이는?

커널이 스레드의 존재를 아는지가 다릅니다.

항목사용자 레벨커널 레벨
관리 주체라이브러리커널
생성과 전환 비용매우 싸다. 모드 전환이 없다상대적으로 비싸다
멀티코어 활용어렵다. 커널은 프로세스 하나로 본다가능하다
하나가 블로킹되면프로세스 전체가 멈춘다그 스레드만 멈춘다

두 번째와 네 번째가 결정적입니다. 사용자 레벨만 쓰면 스레드 하나가 파일을 읽는 동안 나머지도 멈춥니다.

현대 운영체제는 대부분 커널 레벨을 쓰고, 그 위에 경량 실행 단위(코루틴, 고루틴, 가상 스레드)를 올리는 방식이 늘고 있습니다. 커널 스레드 몇 개에 수만 개의 논리 흐름을 얹어 두 장점을 합치려는 시도입니다.

흔한 실수: 사용자 레벨을 옛 기술로만 설명하는 것. 지금의 코루틴이 같은 아이디어를 다시 쓰고 있습니다.

Q.스레드풀을 사용하는 이유는?

스레드를 매번 만들고 없애는 비용을 없애고, 동시 실행 수에 상한을 두기 위해서입니다.

이유내용
생성 비용 제거미리 만들어 두고 재사용한다
개수 제한요청이 몰려도 스레드가 무한히 늘지 않는다
자원 보호문맥 교환 폭증과 메모리 고갈을 막는다
큐잉넘치는 작업을 대기열에 담아 순서대로 처리한다

두 번째가 더 중요합니다. 요청마다 스레드를 만들면 동시 접속 2,000에서 실행 흐름이 2,000개가 되고, 커널이 이들을 번갈아 실행하는 비용만으로 CPU 가 소진됩니다.

풀 크기는 작업 성격으로 정합니다.

작업크기 기준
CPU 중심코어 수 안팎
I/O 대기가 긴 작업코어 수보다 크게. 대기 비율만큼

흔한 실수: 크면 좋다고 보는 것. CPU 중심 작업에서 스레드를 코어보다 많이 두면 교환 비용만 늘어납니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

운영체제 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.