운영체제로 부터 시스템 자원을 할당받는 작업의 단위
또는 컴퓨터에서 실행 중인 프로그램의 인스턴스를 의미한다.
CPU 시간
프로세스가 실행되려면 CPU에서 실행 시간을 할당 받아야한다.
운영체제는 CPU 스케줄러를 통해 여러 브로세스 간의 CPU 시간을 공정하게 분배한다.
메모리
프로세스는 코드, 실행 중의 변수, 버퍼 등을 저장하기 위해 메모리를 필요로한다.
운영 체제는 각 프로세스에 독립적인 메모리 영역을 할당하여
프로세스 간의 데이터를 격리시킨다.
입출력 장치
프로세스는 키보드 ,마무스, 디스플레이 등 입출력 장치를 사용할 수 있다.
운영체제는 프로세스가 이런 장치를 안전하게 사용할 수 있도록 관리한다.
파일 시스템 접근
프로세스는 로컬 파일 시스템이나 원격 파일 시스템에 접근할 수 있다.
운영체제는 파일 시스템에 대한 접근을 관리하며, 필요에 따라 접근 권한을 제어한다.
네트워크 리소스
프로세스는 네트워크 통신을 통해 다른 곳과 데이터를 주고 받을 수 있다.
운영체제는 네트워크 통신을 관리하며 보안을 유지하기 위한 여러 메커니즘을 제공한다.
프로세스는 각각 독립된 메모리 영역(Code, Data, Heap, Stack)을 할당받는다.
소스코드
및상수
를 관리하는 영역이다.
정적 변수
,전역 변수
가 할당되는 영역이다.영역에는
BSS(Block Started by Symbol)
이라는 공간이 있는데
이 곳에초기화되지 않는 변수
들이 저장된다.
정적 변수
프로그램이 시작될 때 메모리에 할당되고 프로그램이 종료될때 메모리에서 해제되는 변수
function counter() { // 'count'는 이 함수 내에서 정의된 정적 변수이다. // 이변수는 함수가 호출될때 마다 초기화되지 않는다. static var count = 0; count++; return count; } console.log(counter()); // 1 console.log(counter()); // 2 console.log(counter()); // 3
사용자가 직접 관리하는 영역으로
데이터가 동적으로 할당
되는 영역이다.
위에서 아래로
쌓인다.
동적 데이터
프로그램이 실행 중에 어떤 데이터를 저장해야하는지 미리 알 수 없거나
데이터가 실행 도중에 변할 수 있는 경우이 예제에서 createUser 함수는 새로운 객체를 동적으로 생성하여 user에 할당한다.
객체의 크기나 수명은 컴파일 시간에 알려져 있지 않으며, 런타임 동안에만 결정된다.여기서 new Object()를 사용하여 객체를 생성하면,
필요한 메모리가 힙에 할당되고, 이 메모리의 주소가 user 변수에 저장다.
따라서 user 변수는 동적으로 생성된 객체를 가리킨다.function createUser(name, age) { var user = new Object(); // 메모리에 객체를 동적으로 할당한다. user.name = name; user.age = age; return user; } var user1 = createUser("Alice", 25); // 이 시점에서 'user1'이라는 객체가 동적으로 생성된다. console.log(user1); // 출력: {name: "Alice", age: 25}
함수의 호출 정보
,지역 변수
가 저장되는 부분이다.
LIFO(Last In First Out)
구조,아래에서 위로
쌓인다.
지역 변수
특정 함수나 블록 내에서만 접근할 수 있는 변수
이 변수는 함수가 호출될때 메모리에 할당되고, 함수가 종료될때 메모리에서 해제한다.
funciton show(){ // 'message'는 이 함수 내에서 정의된 지역 변수이다. var message = "hello world"; console.log(message); } show(); // hello world console.log(message); // ReferenceError: message is not defined
각 프로세스는 별도의 주소 공간에서 실행되며,
한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.한 프로세스가 다른 프로세스의 자원에 접근하려면
프로세스 간 통신(IPC, inter-process communication)을 사용해야한다.
서로 다른 프로세스 간에 데이터를 주고 받는 메커니즘을 의미한다.
한 프로세스의 출력이 다른 프로세스의 입력으로 사용
될 수 있도록 한다.
파일
한 프로세스에서 파일을 쓰고 다른 프로세스에서 그 파일을 읽어들이는 방식
장점
- 구현 간단 및 디버깅 용이
- 모든 운영체제에서 지원
- 데이터는 파일에 영구적으로 저장되므로 프로세스가 종료된 후에도 유지
단점
- 동시에 여러 프로세스가 파일을 변경하려고 하면 충돌이 발생할 수 있음
- 동기화 메커니즘 필요
시그널(Signal)
유닉스 및 리눅스에서 사용되는 소프트웨어 인터럽트.
한 프로세스에서 다른 프로세스로 특정 이벤트가 발생했음을 알리는데 사용된다.
장점
- 구현이 간단
- 운영체제 수준에서 지원되어서 별도의 라이브러리나 프레임워크가 필요없다.
단점
- 시그널은 정보를 전달하는데 제한적이다.
- 대부분의 시그널을 프로세스의 실행을 중단하거나 중단시킨다.
파이프와 소켓
🔴파이프는 같은 시스템에서 실행 중인 프레스 간의 데이터를 전송하는데 사용되는 방식
소켓을 네트워크를 통해 실행 중인 프로세스 간에 데이터를 전송하는데 사용되는 방식
장점
- 실시간 데이터 전송이 가능하다.
- 파이프의 경우 부모-자식 프로세스 간의 통신에 이상적
- 소켓의 경우 네트워크를 통한 프로세스 간 통신에 이상적
단점
- 파이프는 같은 시스템에서만 사용할 수 있다.
- 소켓은 구현이 복잡하다.
메세지 큐(Message Queue)
🔴프로세스 간에 데이터를 전송하는데 사용하는 방식
메세지는 큐에 저장되고 수신 프로세스가 준비되면 메세지를 수신한다.
장점
- 프로세스 간 데이터를 안정적으로 전송한다.
- 큐에 저장된 메세지는 프로세스가 준비될 때까지 기다리므로 별도의 동기화가 필요없다.
단점
- 구현 시 시스템 자원을 많이 소비한다.
- 큐가 가득 차면 메세지를 더이상 추가할 수 없다.
공유 메모리(Shared Memory)
🔴두 개 이상의 프로세스가 동일한 메모리 공간에 접근하여 데이터를 읽고 쓸 수 있도록 한다.
장점
- 빠른 데이터 접근
- 큰 데이터 세트를 공유하는데 효율적
단점
- 공유 메모리 영역에 대한 접근을 동기화하는 메커니즘이 필요
세마포어(Semaphore)
🔴공유 리소스를 제어하는 방법
여러 프로세스가 동일한 리소스를 공유하도록 하되,
한번에 하나의 프로세스만 해당 리소스에 접근할 수 있도록하는 메커니즘
장점
- 여러 프로세스 또는 스레드 간의 동기화를 제공
- 공유 자원에 대한 동시 접근을 허용하는 수를 제한한다.
- 동시 업데이트와 같은 문제를 방지
- 데이터 일관성 유지
- 데드락 방지
데드락
: 두개 이상의 프로세스나 스레드가 서로를 대기하면서 발생하는 현상)- 스핀락에 대한 해결책
스핀락
: 공유 자원에 대한 동시 접근을 제어하는 락(lock)의 한 형태, 락이 해제될 때까지 능동적으로 대기("스핀"), 락이 필요할때 스레드는 락을 획득하려고 시도한다. 만약 다른 스레드가 락을 가지고 있는 경우 해당 스레드는 락이 해제될때까지 무한히 기다린다. 이를 스핀이라고 한다.
- 스핀락이 효과적인 상황
- 락이 금방 해제될 것이 예상되는 경우
- 스레드가 락을 기다리는 동안 다른 일을 할 수 없는 경우
- 고려 사항
- 스핀락은 CPU 자원을 많이 사용하므로 스핀 시간이 길어지면 성능 하락
- 스핀 시간이 긴 경우 다른 유형의 락(세마포어 등)을 고려하는 것이 좋다.
단점
- 복잡하다.
- 프로세스가 세마모퍼를 잠그고 종료하는 경우 다른 프로세스들이 영원히 기다리게될 수 있음
- 이를
locked semaphore
라고 한다.- 우선 순위의 역전
- 높은 우선 순위의 프로세스가 낮은 우선순위의 프로세스의 잠금 해제를 기다리는 상황이 발생
프로세스 내에서 실행되는 여러 흐름의 단위로, 프로세스 내에서 CPU를 사용하는 기본 단위
모든 프로세스는 적어도 하나의 스레드를 가지고 있으며
필ㄹ요에 따라 추가 스레드를 생성할 수 있다.
같은 프로세스 안에 있는 여러 스레드들은 같은
Code
,Data
,Heap
영역을 공유한다.이러한 이유로 한 스레드가 프로세스의 자원을 변경하면
다른 스레드도 그 변경 결과를 즉시 볼 수 있다.단, 동시성 문제를 위해 사용하는 동기화 메커니즘 때문에 실제로 약간의 지연이 발생할 수 있다.
각각의 스레드들은 별도의 레지스터와 스택을 가지고 있다.
JVM에 의해 스케줄링 되는 실행 단위 코드 블록이다.
일반 스레드와 차이가 없으며, JVM이 운영체제의 역할을 한다.
자바는 프로세스가 존재하지 않고 스레드만 존재한다.
개발자는 자바 스레드로 작동할 스레드 코드를 작성하고
스레드 코드가 생명을 가지고 실행을 시작하도록 JVM에 요청하는 일 뿐이다.
- 스레드의 개수
- 스레드로 실행되는 프로그램 코드의 메모리 위치는 어디인지
- 스레드의 상태
- 스레드의 우선 순위