프로세스란 뭔가요? 🧐
프로세스의 개념은 프로그램과 관련 있습니다. 프로그램은 하드웨어에 '정적 상태'로 저장되어 있습니다. 누군가 실행시키지 않는 한 그 상태를 유지합니다. 그럼 프로그램이 실행되어 '동적 상태'로 되는 것은 무엇일까요? 이게 바로 프로세스입니다. 프로그램이 실행되어 메모리에 올라온 상태를 프로세스라고 합니다.
프로세스는 메모리에 올라간다!
프로그램이 실행되면 운영체제는 프로세스를 메모리의 적당한 위치로 가져오고, 프로세스의 정보들을 저장한 PCB(Process Control Block)를 생성합니다. 더 자세히는 프로세스는 메모리의 사용자(유저) 영역에, PCB는 커널 영역에 올라가게 됩니다.
PCB(Process Control Block)
CPU가 프로세스를 실행하기 위해 필요한 프로세스 구분자, 메모리 관련 정보, 프로그램 카운터, 각종 중간값들을 보관하는 데이터 구조입니다. 프로그램이 프로세스가 되려면 메모리에 올라오는 것과 동시에 PCB가 반드시 생성되어야 합니다. 프로세스가 종료되면 프로세스는 메모리에서 삭제되며, PCB도 폐기됩니다.
프로세스의 연산을 처리하는 CPU
실행중인 프로그램의 상태를 프로세스라고 했습니다. 그리고 실행중이라는 뜻은 프로그램에 정의된 코드들의 연산이 처리되는 것을 말합니다. 이 연산을 처리하는 것이 바로 CPU 입니다. 그럼 연산할 코드들은 어디서 얻어오는 걸까요? 바로 스레드입니다. 하나의 프로세스는 무조건 하나 이상의 스레드를 갖습니다. 이 스레드들을 CPU가 처리하는 것입니다.
프로세스 구조
프로세스에 스레드가 하나밖에 없으면 싱글 스레드, 둘 이상이면 멀티 스레드라고 말합니다. 이 둘의 구조적인 차이가 뭘까요? 이를 이해하기 위해서는 먼저 프로세스의 구조를 이해해야 합니다.
코드 영역
프로그램의 코드가 기술된 곳입니다. 프로그래머가 작성한 프로그램은 코드 영역에 탑재되며 탑재된 코드는 읽기전용으로 처리됩니다.
데이터 영역
코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳입니다. 데이터는 변하는 값이기때문에 읽기와 쓰기가 가능합니다. 물론 상수는 읽기 전용입니다.
스택 영역
운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳입니다. 프로세스 내에서 함수를 호출하면 함수 실행 후 돌아올 위치를 이 영역에 저장합니다. 위 예에서는 exit() 함수를 호출했을 때 돌아올 위치가 180이라는 주소임을 말하고 있습니다. 프로그램을 실행하면 운영체제는 프로그램을 메모리의 코드 영역에 넣습니다. 그리고 데이터 영역과 스택 영역을 확보하고 프로세스를 실행합니다. 이와 동시에 PCB도 생성합니다.
스레드가 뭔가요? 🤔
CPU가 처리하는 실행 단위를 말합니다. 한 개 이상의 스레드가 모여 프로세스를 이루기 때문에, 스레드를 프로세스 실행 단위라고도 합니다.
싱글 스레드와 멀티 스레드의 차이
이제 싱글 스레드와 멀티 스레드의 차이를 알아보겠습니다. 싱글 스레드는 앞서 언급한대로 프로세스가 하나의 스레드만을 갖는 것을 말합니다. CPU는 한번에 하나의 스레드만을 처리할 수 있으므로 CPU가 1 개인 시스템에서 프로세스의 실행은 문제가 되지 않습니다. 하지만 현재 시스템은 대부분 여러개의 CPU로 구성되어 있습니다. 필자의 경우 12개의 CPU 코어가 있으니, 동시에 12개의 스레드를 처리할 수 있습니다. 이러한 환경에서 단일 스레드 프로세스를 실행하게 되면 11개의 CPU 코어를 활용하지 못해 시스템의 효율성이 내려가게 됩니다. 이왕이면 여러 개의 스레드가 처리되는게 더 좋겠죠?
프로세스를 여러개 만들면 되는거 아냐? 🤔
그럼 단일 스레드를 갖는 프로세스를 여러개 실행하면 어떻게될까요? 프로세스와 스레드가 새로 생성될것이고 여러 개의 CPU가 이들을 처리하게 될것입니다. 그런데 이 방식은 문제아닌 문제가 있습니다. 바로 프로세스마다 메모리 할당과 PCB 생성을 해야한다는 것입니다.
위에서 프로세스의 구조를 설명했는데 사실 힙 영역이라는 영역이 더 존재합니다. 그리고 힙 영역과 스택 영역은 동적 영역에 해당하는데 동적으로 크기가 줄어들고 늘어나는 영역입니다. 스택 영역은 함수 호출 후 복귀 시 사용하고, 추가로 지역변수를 저장할때 사용됩니다. 참고로 전역변수는 데이터 영역에 저장됩니다. 힙 영역은 프로그램이 실행되는 동안 할당되는 영역으로 자바의 인스턴스나 c언어의 malloc() 함수입니다.
스레드는 프로세스 구조 중 동적영역에 생성됩니다. 아래와 같이 말이죠.
만약 단일 스레드 프로세스를 여러개 실행하면 어떻게될까요? 프로세스 개수만큼의 정적영역이 메모리에 추가로 할당되어야 할것입니다.
또 하나의 문제가 있습니다. 바로 Context Switching 속도가 느리다는 것입니다. 각각의 프로세스를 Context Switching 하는것보다 같은 프로세스를 갖는 스레드에 대해 Context Swtiching하는 속도가 더 빠릅니다.
Context Switching (문맥교환)
CPU를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 작업을 말합니다. 실행 상태에 있던 PCB에는 지금까지의 작업을 저장하고, 실행 상태로 들어오는 PCB의 내용으로 CPU가 다시 셋팅되는 작업입니다. 이와 같이 두 프로세스의 PCB를 교환하는 작업이 문맥교환입니다.
멀티 스레드의 문맥교환이 단일 스레드보다 더 빠른 이유가 뭐야? 🤔
멀티 스레드는 같은 프로세스에 속해있기 때문에 정적인 데이터를 공유하게 됩니다. 데이터 영역과 코드 영역을 공유합니다. 캐시는 CPU에서 읽어들인 메모리의 데이터를 저장하고 있다가 CPU가 다시 데이터를 요구할 때 메모리에서 전달해줍니다. 즉, 문맥 교환이 발생하고 PCB 내용을 기반으로 CPU를 셋팅할때 데이터 영역과 코드영역을 메모리영역에서 빠르게 읽어오게 됩니다. 왜? 프로세스가 같으니까요!
이에 반해 단일 스레드의 경우 PCB가 다르므로 기존에 쌓았던 캐시 데이터는 무의미해지고 CPU가 데이터를 읽어들이면 이를 다시 저장해야합니다. 이런 이유로 단일 스레드보다 멀티 스레드의 문맥교환이 더 빠른것입니다.
그럼 문맥 교환은 언제 일어나는거야? 😲
문맥 교환이 일어나는 상황은 매우 다양하나 대표적으로 두가지가 있습니다. 하나는 CPU가 처리중인 프로세스가 자신에게 주어진 시간을 다 사용했을 때이며, 하나는 인터럽트가 발생했을 때입니다. 인터럽트가 발생하는 상황은 매우 다양합니다. 예를들어 프로세스가 자신에게 주어진 메모리 공간을 넘어가려 한다면 인터럽트 관리 프로세스를 실행시킵니다. 이때 문맥교환이 발생합니다. 그리고 인터럽트 관리 프로세스가 메모리 범위를 넘어서려는 프로세스를 강제 종료하게 됩니다.
멀티 스레드의 장점
첫째, 응답성이 향상됩니다. 한 스레드가 입출력으로 인해 작업이 진행되지 않아도 다른 스레드가 작업을 계속하여 사용자의 작업 요구에 빨리 응답할 수 있습니다.
둘째, 자원을 공유합니다. 프로세스가 가진 자원을 모든 스레드가 공유하게 되어 작업을 원활하게 진행할 수 있습니다.
셋째, 시스템 효율성이 향상됩니다. 여러 개의 프로세스를 생성할 필요가 없어 불필요한 자원의 중복과 메모리 중복을 막고 문맥교환이 빨라집니다. 전반적인 시스템 효율이 향상되는 것입니다.
멀티 스레드의 단점
하나의 스레드에 문제가 생겨 종료될 경우 해당 스레드만 종료되는 것이 아니라 프로세스 전체가 종료됩니다. 인터넷 익스플로러는 멀티 스레드라 탭을 하나 추가할 경우 스레드가 생성된다. 이때 하나의 탭에 문제가 생겨 종료된다면 프로세스 자체가 종료되어 인터넷 익스플로러가 종료되게 됩니다. 이에반에 크롬은 싱글 스레드로 각 탭마다 독립적인 프로세스로 동작합니다. 만약 한 프로세스의 스레드에 문제가 생겨 종료되도, 다른 탭에 미치는 영향이 적습니다. 크롬은 이처럼 다른 스레드가 영향받는 것을 최소화하기 위해 낭비 요소가 있더라도 멀티스레드 대신 멀티태스킹을 사용합니다.
프로세스 상태
프로세스는 CPU 스케줄러에 의해 선별되며 스케줄러가 프로세스의 스레드를 CPU에게 전달하게 됩니다. 이를 '실행 상태' 라고 하는데, 이 외에도 여러 상태들이 있습니다. 한번 알아봅시다.
프로세스의 상태는 시스템마다 다르게 구성됩니다. 일괄 작업 시스템의 경우 생성, 실행, 완료 상태를 갖지만, 우리가 현재 대부분 사용하는 시분할 시스템의 프로세스 상태는 생성, 준비, 실행, 대기, 완료 상태를 갖습니다.
생성 상태
프로그램이 메모리에 올라오고, 운영체제로부터 PCB를 할당받은 상태입니다. 생성된 프로세스는 바로 실행되는 것이 아니라 준비 상태(준비 큐)에서 기다리게 됩니다.
준비 상태
프로세스가 CPU를 얻을때까지 기다리는 상태입니다. 준비 큐라는 곳에서 기다리며 CPU 스케줄러에 의해 관리됩니다.
참고로 CPU가 하나인 컴퓨터에서는 한번에 하나의 프로세스(정확히는 프로세스 내 스레드)만을 실행할 수 있습니다. CPU가 많을수록 준비 상태에 있는 프로세스가 빨리 처리될 것입니다.
CPU 스케줄러
준비 상태에 있는 여러 프로세스 중 다음 실행할 프로세스를 선정하는 일을 담당합니다. 준비 상태의 맨 앞에서 기다리는 PCB와 스레드를 CPU에게 전달하여 작업이 이루어지도록 합니다.
디스패치 (Dispatch)
준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 CPU 스케줄러의 작업을 말합니다.
실행 상태
준비 상태에 있는 프로세스 중 하나가 CPU를 얻어 실제 작업(스레드)을 수행하는 상태를 말합니다. 실행 상태에 들어가는 프로세스의 수는 CPU의 개수만큼입니다. 프로세스마다 할당된 시간(타임 슬라이스)을 다 사용하고도 작업이 끝나지 않는다면 해당 프로세스는 준비 상태로 돌아가 다음 차례를 기다리게 됩니다.
타임 슬라이스 (= 퀀텀)
프로세스에 할당된 작업 시간을 말합니다.
클록
타임 슬라이스가 지났는지를 CPU에게 알려주는 장치입니다. 시간이 끝나면 인터럽트를 발생시켜 CPU에게 알려줍니다.
대기 상태
프로세스가 실행 상태에서 입출력(I/O)을 요청할 경우 입출력이 완료될 때까지 기다리는 상태입니다. 이 상태의 프로세스는 입출력 장치별로 마련된 큐에서 기다립니다. 입출력이 완료되면 입출력 관리자로부터 인터럽트를 받고, 준비 상태로 이동하여 다음 작업 수행을 기다린다.
완료 상태
실행 상태의 프로세스가 주어진 시간 동안 작업을 마치거나 종료되는 상태입니다. 프로세스를 메모리에서 제거하고, PCB를 폐기합니다. 만약 비정상 종료될 경우 코어 덤프가 발생합니다.
코어 덤프
프로세스가 비정상 종료될 경우 강제 종료 직전 메모리 상태를 저장 장치로 옮기는 것
'CS' 카테고리의 다른 글
[CS] 웹 프락시 / Proxy (0) | 2023.09.20 |
---|---|
[CS] HTTP 메시지 (0) | 2023.08.30 |
[CS] URL이란? (0) | 2023.08.30 |
[CS] Web Cache / 웹 캐시란? (0) | 2023.08.23 |