CS 📚

프로세스와 스레드

dalin❤️ 2021. 12. 15. 19:32

알고리즘 스터디에서 CS도 돌아가면서 정리해서 발표하기로 했다. 나는 이번에 프로세스와 스레드에 대해서 정리했다.

프로세스와 스레드에 대해 써볼게요~ 그 전에 먼저 프로그램에 대해서 이야기해볼게요.

프로그램

프로그램이란 무엇일까요?

프로그램이란, 파일이 저장 장치(하드 디스크)에 저장되어 있지만 메모리에는 올라가 있지 않은 정적인 상태( (https://velog.io/@raejoonee/프로세스와-스레드의-차이)를 의미합니다. 프로그램이 실행되려면, 메모리에 올라가야 하는데요. 프로그램이 아직 메모리에 올라가지는 않아서, 실행되고 있지는 않아서 정적이라고 표현했습니다. 실행되지 않은 파일 자체입니다.

프로세스

프로그램을 실행하면 어떻게 될까요? 그러면 그 프로그램이 컴퓨터 메모리에 올라가게 됩니다. 메인 메모리에 프로그램이 올라온 것을 프로세스!라고 합니다. 다르게 말하면, 컴퓨터에서 실행 중인 프로그램(https://terms.naver.com/entry.naver?docId=4383179&cid=59941&categoryId=59941)이라고 할 수 있습니다.


(이미지 출처: https://sunrint10103.tistory.com/entry/운영체제-프로그램과-프로세스)

프로세스가 메모리에 올라갈 때, 운영 체제는 프로세스에게 독립한 메모리 영역을 할당해 주는데요. 이때 코드, 데이타, 스택, 힙 형식으로 할당해줍니다.


(이미지 출처:https://zangzangs.tistory.com/107)

코드 영역에는 말 그래도 프로그램 코드가 기계어로 바뀌어서 있고. 데이터 영역에는 전역 변수, 배열 등이 있습니다. 힙은 프로그래머가 동적으로 사용하는 영역입니다. malloc(), new() 같은 걸로 할당하고 반환한다고 합니다. 스택에는 지역 변수, 매개 변수, 리턴 값 등 잠시 사용되고 사라지는 임시 데이터가 있습니다.


(이미지 출처: Heee's Development Blog)


위 그림처럼 프로세스들은 각각 독립된 메모리 영역을 가지기 때문에, 프로세스는 다른 프로세스의 변수나 자료에 접근할 수 없어요. 그래서 프로세스가 다른 프로세스와 정보를 공유하려면 복잡한 과정을 거쳐야 합니다. 한 컴퓨터 안에서 프로세스끼리 통신하는 방법을 IPC(inter-process communication)라고 합니다. 파이프, 공유 메모리, 소켓 방식 등이 있다고 하는데,, 이 부분까지 설명하면 너무 깊게 들어가는 것 같아서 패스할게요. 관련된 링크입니다. (https://jwprogramming.tistory.com/54)

프로세스의 장단점을 설명하기 위해서는 context-switching이라는 걸 알아야 해서, 그걸 잠깐 설명하고 넘어갈게요.

context-switching

cpu가 여러 프로세스를 처리하는데요. cpu에서 여러 프로세스들을 아주 빠르게 돌아가면서 작업을 처리합니다. 다른 프로세스를 처리하게 될 때, 그때까지 실행되던 프로세스들의 상태 정보를 저장하는 게 필요하겠죠 ?
프로세스들이 대기하면서 해당 프로세스의 상태를 가지고 있다가. 대기하고 있던 그 프로세스의 차례가 되면 이전에 저장해뒀던 프로세스 상태를 복구합니다. 이 과정을 context switching이라고 합니다.


(이미지 출처:https://www.crocus.co.kr/1364)
프로세스 p0와 p1 두 개만 존재한다고 봅시다. p0가 cpu를 점유하고 (executing), p1은 대기중이었습니다. 그러다가 p1은 실행 되고 p0은 대기하고, 또 나중에는 p0이 cpu를 점유해서 실행되고, p1이 대기하는데요. p0가 실행되다가 대기상태로 변할 때, 지금까지 작업해온 내용을 저장합니다. 그리고 p1은 대기하다가 실행될 때, 작업해오던 데이터를 다시 가져옵니다.

이렇게 어떤 프로세스를 실행하다가, 다른 프로세스가 실행되어야 할 때, 기존 프로세스 정보는 PCB(process control block- 프로세스의 메타 데이터를 저장하는 블록.) 에 저장하고 다음 프로세스 정보를 PCB서 가져오는 작업을 context-switching이라고 합니다.

프로세스의 특징

단점)

프로세스는 각각 독립된 메모리 영역이 있어서, 프로세스 간에 정보를 공유해야 할 때는 IPC라는 방법으로 해야 하는데, 어렵고 복잡합니다. (ipc)

프로세스 간 메모리를 공유하지 않아서, 한 프로세스가 새로 만들어지거나 context switching 할 때 시간이 오래 걸립니다.

장점)

프로세스 여러 개 중에 하나에 문제가 생기면, 그 프로세스만 문제 생기지 다른 프로세스는 영향 받지 않습니다.

멀티 프로세스(multi-process)

하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업(태스크)을 처리하도록 하는 것이 멀티 프로세스!
https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html

예를 들어서 여러 사용자가 로그인을 요청하면, 한 프로세스는 매번 한 개 요청만 처리할 수 있는데요. 그래서 부모 프로세스가 fork를 해서 자식 프로세스를 만든다고 볼게요. 이때 부모 자식 관계고 해도, 코드, 데이터, 힙이 다 복사가 되어서 생성됩니다. 그래서 곧 설명할 스레드에 비해서 메모리를 많이 차지하고, 생성될 때 시간도 오래 걸립니다.


(https://sumanaki.tistory.com/127)

이렇게 프로세스 만으로는 한계가 있어서, 스레드가 등장했습니다.

스레드

스레드는 프로세스보다 더 작은 실행 단위! cpu입장에서 최소 작업 단위 !입니다. 만약에 vs code에서 코드 실행시킨 상태로, 코드 수정하고, 코드에 마우스 대면 설명도 나오고 그렇잖아요? 각각 스레드가 이 작업을 각각 담당한다고 생각해볼 수 있습니다.


(이미지 출처: Heee's Development Blog)

스레드는 한 프로세스 안에서 주소 공간, 자원 대부분을 공유합니다. 스택 부분만 따로 할당 받고, 나머지 영역은 서로 공유합니다. 그래서 경량화된 프로세스라고도 이야기합니다.

스레드의 특징

스레드의 장점은 다음과 같습니다.

스택 영역만 다르니까 새로운 스레드 생성, 종료할 때 시간 적게 걸립니다. ipc가 필요한 프로세스 간 통신보다 , 스레드끼리는 메모리를 서로 공유하기 때문에 스레드 간 통신은 더 간단합니다.context-switching할 때, 메모리를 절약할 수 있고 더 빠릅니다. 특정 작업 하는 스레드, 사용자와 커뮤니케이션 하는 스레드가 서로 관련 없으면, 그걸 따로 수행해서 사용자에게 응답 더 빨리할 수 있습니다.

단점, 주의점도 있죠. 아까 말한 것처럼, 스레드 하나가 이상해지면, 그 프로세스 내 모든 스레드가 종료됩니다. 코드, 데이타, 힙 메모리 영역을 공유하기 때문에 어떤 스레드 하나에서 오류가 발생하면 같은 프로세스 내 다른 스레드 모두가 강제 종료되어버립니다. (만약에 프로세스를 실행하다가 오류가 발생해서 그 프로세스가 강제 종료된다면, 다른 프로세스는 어떨까요? 공유하는 파일이 따로 없다면 딱히 영향을 안 주겠죠.)
또한 공유하는 메모리, 파일에 대해서 일관성 있어야 하니까 스레드 간 동기화가 필수적으로 필요합니다. 디버깅이 까다롭고, 주의 깊은 설계가 필요하다고도 합니다.

멀티 스레드

멀티 스레드는 하나의 프로세스가 여러 스레드를 만들어서 사용하는 것을 말합니다. 참고로 싱글 스레드은 하나의 프로세스를 곧 하나의 스레드로 인식하는 것입니다. 싱글 스레드 프로세스는 그냥 프로세스랑 똑같다고 생각해도 될 것 같습니다. 이제부터 멀티 스레드를 볼게요.


(이미지 출처:https://www2.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/4_Threads.html)

싱글 코어일 때의 멀티 스레드를 보겠습니다.


(이미지 출처:http://www.qnx.com/developers/docs/qnxcar2/index.jsp?topic=%2Fcom.qnx.doc.neutrino.getting_started%2Ftopic%2Fs1_procs_Multiple_threads_single_CPU.html)
실제로 동시에! 처리되는 것은 아니지만, 동시에 처리되는 것처럼 보이게 됩니다. concurrency죠.

cpu가 여러 개의 스레드를 빠르게 왔다 갔다 하면서 처리합니다. 그러면 프로세스로 할 때보다 뭐가 좋을까요? 하나의 프로세스라면 만약에 그 프로세스에서 이제 i / o 작업을 하게 되면 전체 프로세스가 대기 상태로 있어야 합니다. 그런데 이제 스레드가 여러 개이면, i/ o 작업을 하는 그 스레드만 대기 상태로 있고, 다른 스레드들은 실행될 수 있습니다.

한번 멀티 코어일 때 멀티 스레드가 어떻게 동작하는지 볼게요.


(이미지 출처:http://www.qnx.com/developers/docs/qnxcar2/index.jsp?topic=%2Fcom.qnx.doc.neutrino.getting_started%2Ftopic%2Fs1_procs_Multiple_threads_single_CPU.html)

실질적으로 동시에 같이 실행됩니다. parallelism. 병렬 처리가 되는 거죠.

참고로 비슷한 단어인 멀티 태스킹과 멀티 프로그래밍도 말씀드리겠습니다.

멀티 태스킹

멀티 태스킹은 하나의 cpu에서 여러 프로세스를 실행하는데, 운영체제의 스케줄링에 의해서 번갈아 가면서 수행하는 것을 의미합니다. cpu는 한 번에 하나의 작업만 할 수 있는데요. 여러 task를 아주 아주 빠르게 번갈아가면서 수행하다 보니, 동시에 여러 프로세스가 실행되는 것처럼 느끼게 됩니다.

이때 스케줄링 방식이 multi-programming, time-sharing, real-time 방식 등이 있습니다.

멀티 프로그래밍

단일 cpu에 여러 개의 프로그램이 동시에(concurrency) 실행되게 한 것입니다.

아주 과거에는 cpu 하나에서 하나의 프로그램만 실행하게 했습니다. 하나의 프로그램만 있으면 i/o 같은 게 일어날 때 cpu가 할 게 없어요. cpu 되게 비싼데,, 낭비 잖아요? 그래서 사람들이 cpu 쉬는 시간에 다른 프로그램을 돌리면 좋겠다고 생각했어요. 그래서 단일 cpu에서 여러 개의 프로그램이 동시에 실행되게 했는데, 그게 바로 멀티 프로그래밍이에요. cpu의 이용률을 높인 거죠! 여기에서 동시에는 ! paralleism이 아니라 concurency를 말합니다. 실제로 동시에!!는 아니고, 아주 빠른 텀을 두고 여러 프로그램이 돌아가면서 수행되는 걸 말해요.

저는 둘의 차이를 확실히는 모르겠어요..
"멀티 프로그래밍은 프로세서의 자원낭비를 막기 위해서 등장한 개념이고, 멀티태스킹은 정해진 시간 동안 각각의 task를 번갈아가며 수행하는 것을 의미한다."라고 정리한 분이 계시네요~ https://oizys.tistory.com/9

처음으로 정리해봤네요.. 강의만 듣던 것보다 글로 정리해보니 이해가 잘되는 것 같아요 :) 
그렇지만 아직 모르는 것이 많아서,, 혹시 틀린 것이 있다면 댓글로 알려주세요~

728x90

'CS 📚' 카테고리의 다른 글

인증 방식(세션-쿠키, JWT 토큰)  (3) 2022.06.13
HTTP 헤더 간단 정리  (0) 2022.04.15
많이 들어 본 Proxy  (0) 2022.03.24
IPC (Inter Process Communication)  (0) 2022.02.09