소프트웨어 개발을 하다 보면 프로세스, 스레드, 메모리 영역, 컨텍스트 스위칭, 레이스 컨디션, 세마포어, 뮤텍스, 그리고 데드락과 같은 개념들을 접하게 된다.
1. 프로세스와 스레드
프로세스(Process)
- 정의: 프로세스는 실행 중인 프로그램의 인스턴스를 의미한다.
- 운영 체제에서 프로그램이 실행되면 해당 프로그램에 대한 프로세스가 생성된다.
- 특징:
- 독립적인 메모리 공간: 프로세스는 고유의 메모리 공간(코드, 데이터, 힙, 스택)을 가지게 된다.
- 자원 할당의 단위: 운영 체제는 프로세스 단위로 메모리, 파일 디스크립터 등의 자원을 할당한다.
- 프로세스 간 통신(IPC): 프로세스들은 서로 독립적이므로 통신하기 위해서는 특별한 메커니즘(파이프, 소켓, 공유 메모리 등)이 필요하게 된다.
스레드(Thread)
- 정의: 스레드는 프로세스 내에서 실행되는 흐름의 단위이다.
- 하나의 프로세스는 여러 개의 스레드를 가질 수 있다.
- 멀티 스레딩을 생각하면 이해가 빠르다.
- 특징:
- 공유 메모리 공간: 같은 프로세스 내의 스레드들은 메모리 공간(코드, 데이터, 힙)을 공유.
- 하지만 각자 자신만의 스택을 가진다.
- 경량 프로세스: 스레드는 프로세스에 비해 생성 및 컨텍스트 스위칭 비용이 적다.
- 동시성: 멀티스레딩을 통해 하나의 프로세스 내에서 동시성을 활용할 수 있다.
- 공유 메모리 공간: 같은 프로세스 내의 스레드들은 메모리 공간(코드, 데이터, 힙)을 공유.
프로세스와 스레드의 차이
구분 | 프로세스 | 스레드 |
---|---|---|
메모리 공간 | 독립적 | 공유(코드, 데이터, 힙) |
스택 | 별도 | 개별적으로 존재 |
통신 방법 | IPC 필요 | 직접 메모리 접근 가능 |
생성 비용 | 높음 | 낮음 |
컨텍스트 스위칭 비용 | 높음 | 낮음 |
2. 메모리 영역
프로그램이 실행되면 운영 체제는 해당 프로그램을 위해 메모리 공간을 할당한다.
이 메모리 공간은 여러 영역으로 나뉘게 된다.
이 부분은 다음을 참고할 수 있다.
1. 코드 영역 (Text Segment)
- 내용: 실행할 기계어 코드가 저장되는 영역.
- 특징: 읽기 전용으로 설정되어 있어 코드의 무결성을 유지한다.
2. 데이터 영역 (Data Segment)
- 초기화된 데이터 영역: 초기값이 있는 전역 변수와 정적 변수가 저장된다.
- 초기화되지 않은 데이터 영역 (BSS): 초기값이 없는 전역 변수와 정적 변수가 저장된다.
3. 힙 영역 (Heap)
- 내용: 동적 메모리 할당(
malloc
,new
등을 통해 할당된 메모리)이 이루어지는 영역이다. - 특징:
- 크기가 동적으로 변함.
- 데이터 영역과 스택 영역 사이의 공간을 자유롭게 활용 가능.
4. 스택 영역 (Stack)
- 내용: 함수 호출 시 생성되는 지역 변수, 매개변수, 반환 주소 등이 저장된다.
- 특징:
- LIFO(Last-In, First-Out) 구조를 가진다.
- 자동으로 할당 및 해제가 이루어진다.
- 재구 호출 등을 통한 스택 오버플로우에 유의해야 한다.
힙과 스택의 차이
구분 | 힙 | 스택 |
---|---|---|
할당 방법 | 프로그래머에 의해 직접 관리 | 컴파일러에 의해 자동 관리 |
속도 | 상대적으로 느림 | 상대적으로 빠름 |
구조 | 동적, 비순차적 | LIFO 구조 |
공간 크기 | 크기가 크며 동적으로 확장 가능 | 크기가 제한적 |
3. 컨텍스트 스위칭 (Context Switching)
정의
컨텍스트 스위칭은 CPU가 하나의 프로세스나 스레드의 상태(Context)를 저장하고,
다른 프로세스나 스레드의 상태를 불러와 실행하는 과정을 의미한다.
왜 필요한가?
멀티태스킹 환경에서 CPU는 여러 프로세스나 스레드를 빠르게 전환하며 실행합니다.
이때 각 작업의 상태를 정확히 유지하기 위해 컨텍스트 스위칭이 필요하다.
저장해 두고 다음에 다시 그대로 실행할 수 있어야 하기 때문.
컨텍스트 스위칭 과정에서 일어나는 작업
- 현재 실행 중인 프로세스/스레드의 상태 저장:
- CPU 레지스터 값 저장
- 프로그램 카운터(PC) 저장
- 기타 실행 상태 정보 저장
- 다음 실행할 프로세스/스레드의 상태 복원:
- 저장된 레지스터 값 복원
- 프로그램 카운터 설정
- 메모리 맵 설정
프로세스 vs 스레드의 컨텍스트 스위칭
- 프로세스 컨텍스트 스위칭:
- 메모리 공간이 변경되므로 오버헤드가 크다.
- 캐시 미스 등이 발생할 수 있다.
- 스레드 컨텍스트 스위칭:
- 같은 메모리 공간을 공유하므로 오버헤드가 적다.
- 레지스터와 스택 포인터만 변경하면 된다.
4. 레이스 컨디션 (Race Condition)
정의
레이스 컨디션은 두 개 이상의 스레드나 프로세스가 공유 자원에 동시에 접근하여,
예상치 못한 결과를 초래하는 상황을 말한다.
예시
- 두 스레드가 동시에 변수
count
를 증가시키려고 할 때, 의도한 결과가 나오지 않을 수 있다.
문제점
- 데이터 불일치로 인한 의도되지 않은 동작 유발
- 동시성 관리 실패로 인한 프로그램의 불안정성
5. 세마포어와 뮤텍스
동시성 문제를 해결하기 위해 다음의 메커니즘이 등장했다.
뮤텍스 (Mutex)
- Mutual Exclusion의 약자
- 특징:
- 상호 배제를 보장.
- 한 번에 하나의 스레드만 임계 영역에 들어갈 수 있다.
- 임계 영역(Critical Section)이란 멀티 프로세스 환경에서 공유자원에 접근하는 코드 부분을 말한다.
- 사용 방법:
- 임계 영역 진입 전에
lock
획득 - 임계 영역 종료 후
lock
해제
- 임계 영역 진입 전에
세마포어 (Semaphore)
- 정의: 공유 자원에 대한 접근을 제한하는 카운터.
- 특징:
- 카운터 값을 통해 동시에 접근 가능한 스레드 수를 제어한다.
- 뮤텍스는 세마포어의 일종으로, 카운터 값이 1인 이진 세마포어라 볼 수 있다.
- 종류:
- 카운팅 세마포어: 카운터 값이 0 이상인 일반적인 세마포어
- 이진 세마포어: 카운터 값이 0 또는 1인 세마포어(뮤텍스와 유사)
세마포어 vs 뮤텍스
구분 | 세마포어 | 뮤텍스 |
---|---|---|
소유권 | 없음 | 락을 획득한 스레드만 해제 가능 |
사용 목적 | 제한된 자원에 대한 접근 제어 | 상호 배제 |
카운터 값 | 0 이상 (카운팅 가능) | 0 또는 1 (이진 상태) |
6. 데드락 (Deadlock)
정의
데드락은 두 개 이상의 프로세스나 스레드가 서로 상대방이 점유한 자원을 기다리며 무한 대기 상태에 빠지는 현상.
데드락 발생 조건
- 상호 배제 (Mutual Exclusion): 자원은 한 번에 하나의 프로세스만 사용할 수 있다.
- 점유 대기 (Hold and Wait): 자원을 점유한 상태에서 다른 자원을 기다린다.
- 비선점 (No Preemption): 다른 프로세스의 자원을 강제로 빼앗을 수 없다.
- 순환 대기 (Circular Wait): 프로세스들이 원형으로 자원을 대기한다.
데드락 해결 방법
- 예방
- 데드락 발생 조건 중 하나를 제거.
- 예: 자원을 한꺼번에 요청하게 하여 점유 대기를 막습니다.
- 짜잘한 요청이 여러 번 락을 반복적으로 거는 것을 막는 것.
- 회피
- 시스템 상태를 모니터링하여 데드락이 발생하지 않도록 자원 할당을 조정합니다.
- 은행가 알고리즘 등이 사용됩니다.
- 탐지 및 복구
- 데드락 발생을 허용하되, 발생 시 이를 탐지하고 복구한다.
- 복구 방법으로는 프로세스 종료, 자원 선점 등이 있다.
결론
프로세스와 스레드는 프로그램의 실행 단위로서, 각각의 고유한 특성을 갖고 있다.
메모리 영역에 대한 이해는 효율적인 메모리 관리와 성능 최적화에 필수적이라고 할 수 있다.
동시성 프로그래밍에서는 이번에 다룬 개념들이 매우 중요하게 다뤄집니다.
특히 서버 개발에 있어 더더욱 중요한 개념들이라고 할 수 있다.
이러한 개념들을 정확히 이해하고 적용함으로써 안정적이고 효율적인 프로그램을 개발할 수 있을 것이다.
'Camp > Standard' 카테고리의 다른 글
컴퓨터에서의 CPU란? (0) | 2024.10.07 |
---|---|
컴퓨터에서의 메모리란? (0) | 2024.10.06 |
[OSI 7계층] 응용 계층 (0) | 2024.09.23 |
[OSI 7계층] 전송 계층 (0) | 2024.09.06 |
[OSI 7계층] 네트워크 계층 (0) | 2024.09.06 |