프로세스
정의: 프로세스는 실행 중인 프로그램의 인스턴스입니다. 독립적인 메모리 공간과 자원을 가지며, 운영체제에 의해 스케줄링과 관리됩니다.
스레드
정의: 스레드는 프로세스 내에서 실행되는 하나의 실행 흐름입니다. 스레드는 프로세스의 메모리와 자원을 공유하면서 동작합니다.
스케줄링
프로세스 스케줄링: 운영체제는 여러 프로세스 중 어떤 프로세스를 CPU에 할당할지 결정하는 역할을 합니다. 이를 위해 다양한 스케줄링 알고리즘이 존재합니다 (Round Robin, Priority Scheduling, FCFS 등).
스레드 스케줄링: 멀티스레딩 환경에서는 스레드 스케줄링이 중요합니다. 스레드 스케줄링은 프로세스 스케줄링보다 더 빠르고 효율적일 수 있습니다.
컨텍스트 스위칭
프로세스 컨텍스트 스위칭: 한 프로세스에서 다른 프로세스로 CPU 제어권을 넘기는 것을 말합니다. 이 때, 현재 실행 중인 프로세스의 상태를 저장하고 새로운 프로세스의 상태를 불러옵니다. 이 과정은 상대적으로 느리고 비용이 많이 듭니다.
스레드 컨텍스트 스위칭: 한 스레드에서 다른 스레드로 제어권을 넘기는 것을 말합니다. 프로세스 컨텍스트 스위칭보다 빠르고 자원을 적게 소모합니다. 이는 스레드가 메모리와 자원을 공유하기 때문입니다.
관련 지식
IPC (Inter-Process Communication): 프로세스 간의 통신 방법으로, 메시지 큐, 파이프, 소켓 등이 있습니다.
TLS (Thread-Local Storage): 각 스레드가 자신만의 저장 공간을 가지게 하는 메모리 영역입니다.
동기화: 멀티스레딩 환경에서 자원을 안전하게 접근하기 위한 방법으로, 뮤텍스, 세마포어 등이 사용됩니다.
이러한 개념들은 운영체제와 시스템 프로그래밍에서 중요한 역할을 하며, 효율적인 프로그램 실행을 위해 필수적으로 알아야 할 지식입니다.
리눅스에서는 주로 "Completely Fair Scheduler (CFS)"라는 스케줄링 알고리즘을 사용합니다. CFS는 리눅스 커널 2.6.23 버전부터 기본 스케줄러로 도입되었습니다. 이 알고리즘은 프로세스나 스레드에게 "공평하게" CPU 시간을 분배하려는 목적으로 설계되었습니다.
리눅스의 스케줄링
CFS는 각 프로세스에게 공평한 CPU 시간을 할당하기 위해 "가상 런타임"이라는 개념을 사용합니다. 가상 런타임은 프로세스가 CPU를 얼마나 사용했는지를 나타내며, 이 값을 기반으로 스케줄링 결정이 이루어집니다. 가상 런타임이 가장 적게 된 프로세스가 다음으로 CPU를 사용하게 됩니다.
CFS는 높은 처리량과 낮은 지연 시간을 동시에 달성하려고 노력하며, 대화형 작업과 배치 작업에 모두 잘 동작하도록 설계되어 있습니다.
프로세스와 스레드의 차이점
프로세스
독립적인 메모리 공간: 각 프로세스는 독립적인 메모리 공간(Code, Data, Heap, Stack)을 가집니다.
자원의 독립성: 프로세스는 독립적인 자원(메모리, CPU 시간, I/O 등)을 할당받습니다.
통신과 동기화: 프로세스 간 통신(IPC, Inter-Process Communication)은 비교적 느리고 복잡합니다. 주로 메시지 큐, 파이프, 소켓 등을 사용합니다.
생성과 종료 오버헤드: 프로세스의 생성과 종료는 상대적으로 느리고 자원을 많이 소모합니다.
안정성: 프로세스는 독립적인 메모리를 사용하기 때문에 하나의 프로세스가 실패하더라도 다른 프로세스에는 영향을 미치지 않습니다.
스레드
메모리 공유: 스레드는 같은 프로세스 내에서 메모리(Code, Data, Heap)를 공유하며, 각각 독립적인 스택을 가집니다.
자원의 공유: 같은 프로세스 내의 스레드는 CPU 시간, I/O 등의 자원을 공유합니다.
통신과 동기화: 스레드 간의 통신은 메모리를 공유하기 때문에 빠르고 간단합니다. 하지만 이로 인해 동기화 문제가 발생할 수 있습니다.
생성과 종료 오버헤드: 스레드의 생성과 종료는 프로세스에 비해 빠르고 자원을 적게 소모합니다.
안정성: 하나의 스레드가 실패하면 같은 프로세스 내의 다른 스레드도 영향을 받을 수 있습니다.