1. Process 개념
1.1 정의
Process는 실행 중인 프로그램(Program in execution)이다. 프로그램 실행은 반드시 순차적(sequential)으로 진행된다.
1.2 Process의 구성 요소

| 영역 | 설명 | 접근 방식 |
|---|---|---|
| Text section | 프로그램 코드 | 함수/전역/정적 변수의 주소로 접근 |
| Data section | Static/Global 변수 저장 | 주소로 접근 |
| Heap section | 동적 할당(Dynamic allocation)을 위한 Free memory pool | 포인터 변수의 주소로 접근 |
| Stack | 함수 호출 및 Context switch에 사용 | 지역 변수의 Offset으로 접근 |
Stack의 역할:
- 함수 호출 시: Parameter, Return address, Local variable 저장
- Context switch 시: PC, Stack pointer 포함 Register 값 저장
2. Process State
Process는 실행되면서 상태(state)가 변한다.

| 상태 | 설명 |
|---|---|
| New | Process가 생성되는 중 |
| Ready | Processor에 할당되기를 기다리는 상태 |
| Running | 명령어가 실행되고 있는 상태 |
| Waiting | 어떤 이벤트(I/O 완료 등)가 발생하기를 기다리는 상태 |
| Terminated | Process 실행이 완료된 상태 |
상태 전이:
New→Ready: admitted (시스템에 진입 허가)Ready→Running: scheduler dispatch (CPU 할당)Running→Ready: interrupt (선점, Time slice 만료 등)Running→Waiting: I/O or event waitWaiting→Ready: I/O or event completionRunning→Terminated: exit
3. PCB (Process Control Block)
OS Kernel 내부의 데이터 구조로, 각 Process를 표현한다 (Linux에서는 task_struct).
PCB에 포함되는 정보:
- Process state: 현재 상태 (New, Ready, Running, Waiting, Terminated)
- Program counter: 다음 실행할 명령어의 주소
- CPU registers: 현재 레지스터 값들
- CPU scheduling information: 우선순위, 스케줄링 큐 포인터 등
- Memory-management information: 할당된 메모리 정보
- Accounting information: CPU 사용 시간, 경과 시간 등
- I/O status information: 할당된 I/O 장치, 열린 파일 목록 등
4. Context Switch

CPU가 다른 Process로 전환할 때:
- 현재 Process의 상태를 PCB에 저장(Store): Registers → PCB
- 새 Process의 PCB에서 상태를 복원(Restore): PCB → Registers
특징:
- Context switch time은 순수한 오버헤드(overhead) - 전환하는 동안 유용한 작업이 수행되지 않는다
- 주로 메모리 연산으로 구성되어 느리다
- 하드웨어 지원에 크게 의존 (Intel CPU는 HW 기반 Context switching 지원)
- Context switch 후 Cache flush가 발생하여 연속적인 Cache miss가 일어난다
5. Process Scheduling
5.1 Scheduling Queue

| Queue | 설명 |
|---|---|
| Job Queue | 시스템에 있는 모든 Process의 집합 |
| Ready Queue | Main memory에 올라와 있고, 실행 준비가 된 Process의 집합 |
| Device Queue | 특정 I/O 장치를 기다리는 Process의 집합 |
Process는 이 Queue들 사이를 이동(migration)한다.
5.2 Process Scheduling 흐름

Process가 CPU를 받아 실행되다가 다음과 같은 이유로 Ready queue나 다른 Queue로 이동한다:
- I/O request - I/O queue에서 대기
- Time slice expired - Ready queue로 복귀
- Fork a child - Child가 실행
- Wait for an interrupt - Interrupt 발생 시 복귀
5.3 Scheduler 종류
| Scheduler | 실행 빈도 | 역할 |
|---|---|---|
| Long-term scheduler (Job scheduler) | 매우 드물게 (초-분 단위) | 어떤 Process를 Ready queue에 넣을지 선택. Degree of multiprogramming 제어 |
| Short-term scheduler (CPU scheduler) | 매우 빈번 (밀리초 단위) | 다음에 CPU를 받을 Process를 선택하고 할당. 빨라야 한다 |
| Medium-term scheduler | 필요 시 | Swapping으로 메모리 관리 |

5.4 Process 유형
| 유형 | 특징 |
|---|---|
| I/O-bound process | I/O에 시간을 더 많이 소비. 짧은 CPU burst가 많음 |
| CPU-bound process | 연산에 시간을 더 많이 소비. 길고 적은 CPU burst |
Long-term scheduler는 I/O-bound와 CPU-bound의 적절한 조합(mix)을 선택해야 한다.
6. Process 생성 (Process Creation)
6.1 기본 개념
- Parent process가 Children process를 생성하고, 이 Children이 다시 다른 Process를 생성 - Process tree 구조
- PID(Process Identifier)로 각 Process를 식별
6.2 자원 공유 옵션
- Parent와 Children이 모든 자원을 공유
- Children이 Parent 자원의 일부(subset)를 공유
- Parent와 Child가 자원을 공유하지 않음
6.3 실행 옵션
- Parent와 Children이 동시에(concurrently) 실행
- Parent가 Children이 종료될 때까지 대기
6.4 UNIX에서의 fork()와 exec()
fork(): 새로운 Process를 생성. Child process는 Parent의 Context(PC, 레지스터, 메모리 정보, 열린 파일 등)를 그대로 복사받는다exec():fork()이후 호출하여 Process의 메모리 공간을 새 프로그램으로 교체
fork()의 반환 값:
- Child process:
0을 반환 - Parent process: Child의 PID를 반환
- 실패 시:
-1(음수)
#include <stdio.h>
void main(int argc, char *argv[]) {
int pid;
pid = fork();
if (pid < 0) { /* error */
fprintf(stderr, "Fork Failed\n");
exit(-1);
}
else if (pid == 0) { /* child process */
execlp("/bin/ls", "ls", NULL);
}
else { /* parent process */
wait(NULL); /* child 종료 대기 */
printf("Child Complete\n");
exit(0);
}
}7. Process 종료 (Process Termination)
- Process가 마지막 명령어를 실행하고 OS에 삭제를 요청 (
exit()) - Child → Parent로
wait()를 통해 데이터 전달 가능 - OS가 Process의 자원을 회수(Deallocate)
Parent가 Child를 강제 종료하는 경우 (abort):
- Child가 할당된 자원을 초과했을 때
- Child에게 할당된 작업이 더 이상 필요 없을 때
- Parent가 종료되는데 OS가 Child의 단독 실행을 허용하지 않을 때 - Cascading termination (연쇄 종료)
8. IPC (Interprocess Communication)
시스템 내 Process는 독립적(Independent)이거나 협력적(Cooperating)이다.
8.1 협력(Cooperating)의 이유
- Information sharing: 정보 공유
- Computation speedup: 연산 가속 (병렬 처리)
- Modularity: 모듈화
- Convenience: 편의성
8.2 IPC의 두 가지 모델
| 모델 | 설명 |
|---|---|
| Shared Memory | 프로세스들이 공유 메모리 영역을 통해 데이터 교환 |
| Message Passing | 프로세스들이 send()/receive() 연산으로 메시지를 주고받음. 공유 변수 없이 통신 |
8.3 Producer-Consumer 모델
Shared memory 기반 협력 프로세스의 전형적인 패러다임:
- Producer: 데이터를 생산하여 공유 메모리(Buffer)에 저장
- Consumer: 공유 메모리의 데이터를 소비
| Buffer 유형 | 설명 |
|---|---|
| Unbounded-buffer | Buffer 크기에 실질적 제한 없음 |
| Bounded-buffer | Buffer 크기가 고정됨 |
8.4 Message Passing의 동기화
| 방식 | 유형 | 설명 |
|---|---|---|
| Blocking send | Synchronous | 메시지가 수신될 때까지 Sender가 블록 |
| Blocking receive | Synchronous | 메시지가 도착할 때까지 Receiver가 블록 |
| Non-blocking send | Asynchronous | Sender가 메시지를 보내고 즉시 계속 진행 |
| Non-blocking receive | Asynchronous | Receiver가 유효한 메시지 또는 null을 받고 즉시 계속 진행 |
9. Thread
9.1 개념

Thread(Lightweight process)는 CPU 활용의 기본 단위이며, 다음으로 구성된다:
- Program counter
- Register set
- Stack space
Thread가 공유하는 것 (같은 Process 내의 Peer thread와):
- Code section
- Data section
- OS 자원 (열린 파일, Signal 등)
전통적인 Heavyweight process = 하나의 Thread를 가진 Task
9.2 Thread의 장점
| 장점 | 설명 |
|---|---|
| Responsiveness | 프로그램의 일부가 Block되어도 나머지가 계속 실행 가능 |
| Resource Sharing | 여러 Thread가 같은 Address space 내에서 활동 |
| Economy | Process보다 Thread의 생성과 Context switch가 훨씬 경제적 |
| Scalability | 각 Thread가 서로 다른 Processor에서 병렬 실행 가능 |
9.3 User Thread vs Kernel Thread
| User Thread | Kernel Thread | |
|---|---|---|
| 관리 주체 | User-level Thread library | Kernel |
| 생성/관리 속도 | 빠름 | 느림 |
| Blocking 시 | 하나의 Thread가 Blocking system call을 하면 전체 Process가 Block (Single-threaded kernel의 경우) | 하나의 Thread가 Block되어도 같은 Process의 다른 Thread는 계속 실행 |
| MP 환경 | Kernel이 Thread 존재를 모르므로 여러 Processor에 분배 불가 | Kernel이 Thread를 여러 Processor에 스케줄링 가능 |
| 예시 | POSIX Pthreads, Mach C-threads, Solaris threads | Windows, Solaris, Linux, Tru64 UNIX |
10. Threading Issues
10.1 fork()와 exec()의 의미
Multi-threaded 프로그램에서 한 Thread가 fork()를 호출하면:
exec()을 바로 호출하는 경우: 모든 Thread를 복제할 필요 없음 - 새 프로그램이 Address space를 대체하므로exec()을 호출하지 않는 경우: 모든 Thread가 복제됨
10.2 Thread Cancellation
| 방식 | 설명 | 문제점 |
|---|---|---|
| Asynchronous cancellation | 대상 Thread를 즉시 종료 | 자원 해제 문제, 공유 데이터 무결성 문제 |
| Deferred cancellation | 대상 Thread가 주기적으로 종료 여부를 확인하여 스스로 정상 종료 | 안전하지만 반응이 느림 |
10.3 Signal Handling
UNIX 시스템에서 Signal로 특정 이벤트 발생을 Process에 알린다.
Signal 전달 옵션:
- 해당 Signal이 적용되는 Thread에만 전달
- Process의 모든 Thread에 전달
- 특정 Thread들에만 전달
- 모든 Signal을 받을 전용 Thread를 지정
10.4 Thread Pool
- 미리 일정 수의 Thread를 생성해 놓고, 요청이 오면 Pool에서 가져다 쓰는 방식
- 빠른 서비스: Thread를 매번 새로 만들 필요 없음
- Thread 수 제한: 동시 존재하는 Thread 수를 제한하여 시스템 자원 보호
10.5 Thread-Specific Data
- 각 Thread가 특정 데이터의 자체 복사본을 가져야 하는 경우
- 예: 트랜잭션 처리에서 각 Thread에 고유 식별자(TID) 부여
11. Multicore Programming
Multicore 시스템은 프로그래머에게 다음과 같은 도전 과제를 제시한다:
- Dividing activities: 작업을 어떻게 나눌 것인가
- Balance: 각 부분의 작업량을 균등하게 배분
- Data splitting: 데이터를 어떻게 분할할 것인가
- Data dependency: 데이터 의존성 관리
- Testing and debugging: 병렬 프로그램의 테스트와 디버깅