프로그램과 프로세스
💡 프로그램 : 파일이 저장 장치에 저장되어 있지만, 메모리에는 올라가 있지 않은 정적인 상태
✅ 메모리에 올라가 있지 않은 : 아직 운영체제가 프로그램에게 독립적인 메모리 공간을 할당해주지 않았다.
💡 프로세스 : 운영체제로부터 필요한 메모리와 자원을 할당받아 실행되는 작업의 단위로서, 각 프로세스는 독립된 메모리 공간을 가지고 움직이기 때문에, 한 프로세스가 다른 프로세스의 변수나 자료구조에 접근할 수 없다. 프로세스 간의 데이터를 공유하려면 IPC(Inter-Process Communication)와 같은 특별한 기법을 사용해야 한다.
-
윈도우의 *.exe
파일이나 Mac의 *.dmg
파일과 같은 컴퓨터에서 실행할 수 있는 파일로, 아직 실행하지 않은 상태이기 때문에 정적 프로그램으로도 불린다.
-
모든 프로그램은 운영체제가 실행되기 위한 메모리 공간을 할당해 줘야 실행될 수 있다.
- 프로그램을 실행하는 순간 파일은 컴퓨터 메모리에 올라가게 되고, 운영체제로부터 시스템 자원(CPU)을 할당받아 프로그램 코드를 실행시킨다.
✅ 운영체제(OS, Operating System) : 컴퓨터 시스템의 핵심 소프트웨어로, 컴퓨터 하드웨어와 응용 프로그램 간의 상호작용을 관리하고 제어하는 것
☑️ 목적 : 사용자와 하드웨어 사이의 인터페이스를 제공하고 시스템 자원을 효율적으로 관리하여, 응용 프로그램이 원활하게 동작할 수 있도록 한다.
- 프로세스 : 프로그램을 실행 시켜 정적인 프로그램이 동적으로 변하여 프로그램이 돌아가고 있는 상태
프로그램 |
프로세스 |
어떤 작업을 하기 위해 실행할 수 있는 파일 |
실행되어 작업중인 컴퓨터 프로그램 |
파일이 저장 장치에 있지만 메모리에는 올라가 있지 않은 정적인 상태 |
메모리에 적재되고 CPU 자원을 할당받아 프로그램이 실행되고 있는 상태 |
스레드
💡 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위로서, 같은 프로세스 내에서 힙 메모리를 공유하고, 각 스레드는 개별 스택 메모리를 가지고 있어 독립적인 실행 흐름을 유지한다.
- 과거에는 프로그램 실행에 하나의 프로세스만을 사용하여 작업했지만, 프로그램이 복잡해지고 다양해짐에 따라 이런 방식에는 한계가 있었다.
- 동일한 프로그램을 여러 개의 프로세스로 만들게 되면, 그만큼 메모리를 차지하고 CPU에서 할당받는 자원이 비효율적으로 사용될 수 있다.
- 운영체제는 안전성을 위해서 프로세스마다 자신에게 할당된 메모리 내의 정보에만 접근할 수 있도록 제약을 두고 있고, 이를 벗어나는 정보에 접근하려면 오류가 발생한다.
- 이러한 프로세스 특성의 한계를 해결하기 위해 스레드가 나왔다.
- 스레드 : 하나의 프로세스 내에서 동시에 진행되는 작업의 갈래, 흐름의 단위
- 일반적으로 하나의 프로그램은 하나 이상의 프로세스를 가지고 있고, 하나의 프로세스는 반드시 하나 이상의 스레드를 갖는다.
- 즉, 프로세스를 생성하면 기본적으로 하나의 main 스레드가 생성된다.
프로세스와 스레드의 메모리
프로세스의 자원 구조
- 프로그램이 실행되어 프로세스가 만들어지면 4가지 메모리 영역으로 구성되어 할당 받는다.
코드 영역(Code / Text)
- 프로그래머가 작성한 프로그램 함수들의 코드가 CPU가 해석 가능한 기계어 형태로 저장되어 있다.
데이터 영역(Data)
- 코드가 실행되면서 사용하는 전역 변수나 각종 데이터들이 모여있다.
- 데이터 영역은
.data
, .rodata
, .bss
영역으로 세분화 된다.
- .data : 전역 변수 또는 static 변수 등 프로그램이 사용하는 데이터를 저장
- .bss : 초기값 없는 전역 변수, static 변수가 저장
- .rodata : const 같은 상수 키워드로 선언된 변수나 문자열 상수가 저장
스택 영역(Stack)
- 지역 변수와 같은 호출한 함수가 종료되면 되돌아올 임시적인 자료를 저장하는 독립적인 공간
- 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.
- 만일 stack 영역을 초과하면 stack overflow 에러가 발생한다.
힙 영역(Heap)
- 생성자, 인스턴스와 같은 동적으로 할당되는 데이터들을 위해 존재하는 공간
- 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
Stack과 Heap 영역 사이의 화살표
- 코드 영역과 데이터 영역은 선언할 때 크기가 결정되는 정적 영역이지만, 스택 영역과 힙 영역은 프로세스가 실행되는 동안 크기가 늘어났다 줄어들기도 하는 동적 영역이다.
스레드의 자원 공유
- 스레드 : 프로세스가 할당 받은 자원을 이용하는 실행의 단위
- 스레드끼리 프로세스의 자원을 공유하면서 프로세스 실행 흐름의 일부가 되기 때문에 동시 작업이 가능하다.
- 따라서 한 프로세스 내에서 여러 스레드가 동시에 실행되면서 각각 다른 작업을 처리할 수 있습니다.
- 이때 프로세스의 4가지 메모리 영역(Code, Data, Heap, Stack) 중 스레드는 Stack만 할당 받아 복사하고 Code, Data, Heap은 프로세스 내의 다른 스레드들과 공유된다.
- 따라서 각각의 스레드는 별도의 stack을 가지고 있지만, heap 메모리는 공유하기 때문에 서로 다른 스레드에서 가져와 읽고 쓸 수 있게 된다.
- 반면에 프로세스는 기본적으로 프로세스 끼리 다른 프로세스의 메모리에 직접 접근할 수 없다.
- stack은 함수 호출 시 전달되는 인자, 되돌아갈 주소값, 함수 내에서 선언하는 변수 등을 저장하는 메모리 공간으로, 독립적인 스택 메모리를 가지며, 이를 통해 독립적인 실행 흐름을 유지할 수 있다.
이렇게 구성한 이유 : 하나의 프로세스를 다수의 실행 단위인 스레드로 구분하여 자원을 공유하고, 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 올리기 위해서다.
프로세스의 자원 공유
- 기본적으로 각 프로세스는 메모리에 별도의 주소 공간에서 실행되기 때문에, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
HOW)
- IPC(Inter-Process Communication) 사용
- LPC(Local inter-Process Communication) 사용
- 별도로 공유 메모리를 만들어서 정보를 주고받도록 설정
- BUT) 프로세스 자원 공유는 단순히 CPU 레지스터 교체뿐만이 아니라 RAM과 CPU 사이의 캐시 메모리까지 초기화되기 때문에 자원 부담이 크다는 단점이 있다.
✅ CPU 레지스터 : CPU 내부에 위치한 매우 빠른 메모리로, 프로세스나 스레드의 상태를 저장하는 데 사용된다. 프로세스나 스레드가 실행을 재개할 때 이전 상태를 복원하는 데 필요한 정보를 담고 있다.
- HOW) 다중 작업이 필요한 경우 멀티(다중) 스레드를 이용하는 것이 효율적이다.
멀티 스레드
- 하나의 프로세스 안에 여러 개의 스레드가 있는 것으로, 하나의 프로그램에서 두가지 이상의 동작을 동시에 처리하도록 하는 행위가 가능해진다.
- 즉, 하나의 스레드가 지연되더라도, 다른 스레드는 작업을 지속할 수 있게 된다.
- 예시) : 사용자가 서버 데이터베이스에 자료를 요청하는 동안 브라우저의 다른 기능을 이용할 수 있다.
과제
- 컴퓨터의 병행 처리
- 프로세스와 스레드의 생명 주기
- 멀티 프로세스와 멀티 스레드
참고 사이트