프로세스는 실행 중인 프로그램 자체를 의미하며 우리가 실행하는 프로그램은 각자 독립적인 메모리 공간을 가지며 운영체제가 프로세스를 생성하고 관리한다.
각 프로세스는 자신만의 독립적인 메모리 영역을 가지고 있어 다른 프로세스의 메모리에 직접 접근이 불가하고, 이 덕분에 안전하게 실행될 수 있지만 프로세스 간 데이터를 주고받는게 느리고 복잡하다.
프로세스 스케줄링은 여러 프로세스가 CPU를 사용하려고 대기상태일 때 운영체제가 어떤 프로세스에게 CPU를 할당할지 결정하는 과정으로 이를 통해 여러 프로그램이 동시에 실행되는 것처럼 보여진다.
스레드는 프로세스 내부에서 작업을 수행하는 작은 실행 단위라고 볼 수 있고 한 프로세스 안에는 여러 스레드가 있다. 이들이 협력하여 작업을 빠르게 처리한다.
같은 프로세스에 속한 스레드는 서로 메모리를 공유하며 같은 데이터를 쉽게 사용할 수 있다. 이로 인해 빠르게 통신할 수 있지만 공유 데이터 관리를 신경쓰지 않으면 데이터가 꼬이거나 예기치 않은 동작이 발생할 수 있다.
구분 | 프로세스 | 스레드 |
---|---|---|
메모리 | 독립된 메모리 공간 | 같은 프로세스 내에서 메모리 공유 |
속도 | 느림 | 빠름 (데이터 공유가 쉬움) |
안전성 | 다른 프로세스 간 간섭 없음 | 간섭 가능성 있음 |
생성 비용 | 높음 | 낮음 |
프로세스가 실행되면 메모리는 코드, 데이터, 힙, 스택으로 크게 4가지로 나눠진다.
프로그램의 실행 코드가 들어있는 영역으로서 불변 영역으로 여기에 있는 코드는 변경되지 않는다.
전역 변수와 정적 변수가 저장되는 영역으로 프로그램이 시작될 때부터 끝날 때까지 유지된다.
동적으로 할당된 데이터가 저장되는 영역으로 필요할 때마다 메모리 할당 해제가 가능하다. 다만, 힙 영역은 관리를 프로그래머가 하기 때문에 잘못하면 메모리 누수가 발생할 수 있다.
함수 호출 시 생성되는 지역 변수와 매개 변수가 저장된느 영역으로 함수가 종료되면 자동으로 해제된다.
스택은 함수 호출에 필요한 데이터 관리에 적합하짐나 크기가 제한되어 있어 너무 많은 데이터를 저장하기 어려운 점이 있다.
컨텍스트 스위칭은 하나의 프로세스나 스레드에서 다른 프로세스나 스레드로 CPU가 전환될 때, 이전 상태를 저장하고 새 상태를 로드하는 과정을 뜻한다. 여러 작업이 동시에 실행되는 것처럼 보이도록 하기 위해 컨텍스트 스위칭은 필수이다.
구분 | 프로세스 컨텍스트 스위칭 | 스레드 컨텍스트 스위칭 |
---|---|---|
메모리 접근 | 독립적 메모리, 전환 시 메모리 맵 변경 | 메모리 공유, 같은 프로세스 내에서 스택만 교체 |
비용 | 높음 | 낮음 |
속도 | 느림 | 빠름 |
안전성 | 높음 | 낮음 (다른 스레드의 데이터 접근 가능) |
레이스 컨디션은 여러 프로세스나 스레드가 공유 자원에 동시에 접근할 때 발생하는 문제로 각 작업이 자원에 접근하는 순서에 따라 결과가 달라진다.
예를 들어 은행 계좌 잔액 조회 및 수정 간 여러 스레드에서 작업이 동시에 수행되면 잘못된 금액이 저장될 수 있다.
이를 해결하기 위하여 임계구역을 설정하여 공유 자원에 접근하는 코드가 동시에 실행되지 않도록 제어해야 하는데 여기서 사용되는 대표적인 동기화 도구가 세마포어와 뮤텍스이다.
뮤택스는 한번에 하나의 스레드만 임계 구역에 접근할 수 있도록 하는 Lock 장치로 뮤택스 객체를 잠금 및 해제 함으로써 스레드가 자원에 동시에 접근할 수 없도록 한다.
만약 한 스레드가 뮤택스를 잠그면 다른 스레드는 이 자원에 접근할 때 뮤택스가 해제되기 전까지 대기한다.
그래서 주의해야 할 것이 락을 걸고 해제하는 작업을 잊으면 안된다.
세마포어는 한번에 여러 개의 스레드가 자원에 접근할 수 있게 조절하는 락장치로 카운터를 가지고 있어서 여러개의 스레드가 동시에 자원에 접근할 수 있다.
데드락은 두 개 이상의 프로세스나 스레드가 서로 자원을 기다리며 무한적으로 멈추는 현상을 말한다.
즉 서로가 해제를 안해서 이뤄지는 경우라고 볼 수 있다.
저 위에 기재한 4가지 조건 중 한가지를 없애는 방식으로 자원에 대한 요청 방식을 제한하여 데드락을 미리 방지한다.
뱅커스 알고리즘 같은 방식으로 데드락이 발생하지 않게 미리 자원을 할당하는 방법이 있다. 다만 시스템이 안전한 상태를 유지할 수 있을 때만 자원을 할당한다.
데드락이 발생할 시점에서 주기적으로 검사하여 발생했는지 확인하고 발생 즉시 프로세스 종료 또는 자원 강제 해제를 수행한다.
프로세스와 스레드 간의 동시성 문제는 시스템 안정성과 성능에 큰 영향을 미친다. 이를 관리하기 위해 컨텍스트 스위칭, 뮤택스, 세마포어, 데드락 방지 및 해결 방법을 이해하고 활용하는 것이 중요하다.
다양한 동시성 문제를 미리 예측하고 대비함으로써 시스템을 효율적으로 설계할 수 있으며, 이를 통해 프로그램이 여러 작업을 안전하고 빠르게 처리할 수 있도록 보장할 수 있다.