안녕하세요.
프로세스와 스레드 발표를 맡은 개발오조 이서이 입니다.
저희 개발오조가 선정한 주제는 프로세스 vs 스레드이며 조장은 김남수님, 조원은 김소영님,저,한대희님,홍성우님 으로 구성되어있습니다.
발표는 저와 김남수님이 파트를 나누어서 진행하겠습니다.
그럼 지금부터 발표를 시작하겠습니다.
다들 한 번쯤 들어보셨을 단어일겁니다. 그치만 누군가가 이 단어들에 대해 질문하였을 때 정확하게 설명하기 모호하셨을겁니다.
면접에서도 단골 질문이라는 프로세스와 스레드!
그 개념을 확실히 짚어드리겠습니다.
목차로는
프로그램과 메모리영역,
프로세스,
멀티프로세스
스레드
멀티스레드
마지막으로,
질문받는 시간 갖고 마무리 하는 식으로 진행하겠습니다.
첫번째 챕터 프로그램과 메모리 영역에 대해 알아보겠습니다.
먼저 프로그램이란,
사전적 의미론 어떤작업을 하기위해 해야할 일들을 순서대로 나열한 것으로, 풀어말하면 컴퓨터에서 어떤 작업을 위해 실행할수 있는 정적인 상태의 파일이라고 볼 수 있습니다.
알기쉽게, 한마디로 윈도우의 .exe 파일이나 MacOs .dmg 파일 등 사용자가 눌러서 실행하기전의 파일을 말합니다.
종류로는 흔히 볼수있는 웹브라우저(크롬,엣지 등),카카오톡,워드 프로세서가 있죠.
메모리영역을 말씀드리기전에 프로그램이 어떤식으로 실행되는지 순서를 살펴보자면,
사용자가 os에 프로그램 실행요청을 하면 보조기억장치가 프로그램의 정보를 읽어 메모리에 로드되는데 그럼 이때 os는 메모리에 공간을 할당해 줍니다. 할당해주는 메모리공간은 4가지인데 (code,data,stack,heap) 이 있습니다.
앞에서 메모리영역에 대해 용어만 간단히 말씀드렸는데 더 자세히 설명해볼게요.
맨위의 부분이 실행할 프로그램의 코드가 저장되는 영역, 코드 영역 입니다.
코드영역은 프로그래머가 작성한 프로그램이 코드 영역에 작성이 되고 프로세스가 종료될 때까지 유지되는 영역입니다.
두번째는 전역변수와 static변수가 할당되는 영역인 데이터 영역 입니다.
데이터영역은 코드가 실행되면서 사용한(전역변수, 정적변수), 배열, 구조체 등 파일들의 각종 데이터들을 저장한 공간이며 이 영역 또한 프로세스의 종료까지 유지됩니다.
세번째는 동적으로 할당된 변수가 할당되는 영역인 힙 영역 입니다.
힙 영역은 사용자가 직접 관리하는 영역이며 사용자에 의해 메모리공간이 동적으로 할당되고 해제되고 런타임시에 크기가 결정됩니다.
네번째는 스택 영역 입니다.
프로그램이 자동으로 사용하는 임시 메모리 영역입니다.
함수호출시 생성되는 지역변수와 매개변수가 저장되는 영역이고 함수 호출이 완료되면 사라집니다.
사실 위의 힙과 스택영역은 같은공간을 공유하는데 heap이 메모리 위쪽 주소부터 할당되면 stack은 아래쪽부터 할당되는 식입니다. 그래서 각 영역이 상대공간을 침범하는 일이 발생할수 있는데 이를 각각 힙 오버플로우, 스택 오버플로우 라고 말합니다.
또, 스택영역이 크면 클수록 힙 영역이 작아지고, 반대로 힙 영역이 크면 클수록 스택 영역이 작아집니다.
다음은 프로세스 입니다.
프로세스란 뭘까요? 여기에 대해 간단하게 말하면, 아까 프로그램은 실행되지않은 파일 그자체를 가리키는 말이라고 설명드렸어요. 그럼 그 프로그램을 실행한게 바로 프로세스 입니다.
이제 좀 더 자세히 알아봅시다.
프로그램을 실행하는 순간 해당 파일은 컴퓨터 메모리에 올라가게 되고, 이 상태를 동적인 상태라고 하며 이 상태의 프로그램을 프로세스 라고 합니다.
방금 프로세스가 메모리에 올라갈 때 운영체제로부터 시스템 자원을 할당받는다고 언급했었는데,
운영체제는 프로세스마다 각각 독립된 메모리영역(code,data,stack,heap)의 형식으로 할당해 줍니다.
각각 독립된 메모리영역을 할당해주기 때문에 프로세스는 다른 프로세스의 변수나 자료에 접근할수 없어요.
또한, 기본적으로 프로세스는 최소 1개의 스레드를 가지고 있습니다.
이 스레드를 메인스레드라고합니다.
이번엔 멀티프로세스에 대해 알아봅시다.
멀티프로세스는 하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것이며,
각 프로세스 간 메모리 구분이 필요하거나 독립된 주소공간을 가져야 할 경우 사용합니다.
여러분의 완벽한 이해를 돕기 위해 예시를 들어 설명해보겠습니다.!
혹시 여러분 '스타크래프트'라는 게임을 아시나요??
아마 다들 한 번쯤은 들어보셨을 겁니다!
이 게임에서 상대방과 전투하기 위해서는 '마린'이라는 유닛을 생성해야 합니다. '마린'을 생성하기 위해서는 '베럭'이라는 건물이 필요하고요..
게임 유저의 목표가 마린 12마리를 생성해 전투하는 건데, 마린 1마리를 생성하는데 1초가 걸린다고 가정해봅시다.
하나의 베럭에서 12마리의 마린을 생성하기위해, 시간이 얼마나 걸릴까요??
당연히 12초가 걸릴겁니다.
하지만,
2개의 베럭에서 생성을 한다면?? 6초가 걸리겠죠??
여기서 '베럭'을 프로세스라고 한다면, 이해가 쉬우실 겁니다.
1개의 베럭에서 생성하는 것이 단일 프로세싱(프로세스가 하나인 것)
그리고,
2개의 베럭에서 생성하는 것을 멀티 프로세싱 이라고 이해하시면 될 것 같습니다.
추가로 여기서 중요한 점은,
각각의 베럭은 각자 마린을 몇마리 생성하였는지, 또는 베럭을 지을 때 얼마만큼의 자원을 소모하였는지 다른 베럭들과 공유하지 않는다는 겁니다.
즉,
프로세스는 고유의 메모리 영역을 할당받았기 때문에, 각자의 Code, Data, Heap, Stack 영역을 공유하고 있지 않다는 점.!!
꼭 기억 해주세요!
자, 그럼 다들 프로세스와 멀티프로세스에 대해 완벽히 이해하셨을테니,
이번엔 멀티프로세스에 장단점에 대해 말해볼게요.
우선 장점인데,
여러 개의 자식 프로세스 중 하나에 문제가 발생해도,
자식 프로세스만 죽는 것 이상으로 다른곳으로 영향이 확산되지 않아 안정성이 높습니다.
왜냐하면 앞서 말씀 드린 것처럼 프로세스 간에 메모리는 공유하지 않기 떄문입니다.
그래서 작업속도가 느려지는 손해는 생기지만 정지되거나 하는 문제는 발생하지 않아요.
두번째는, 구현이 비교적 간단합니다.
반대로 단점으로는,
컨텍스트 스위칭 과정에서 캐쉬메모리(코드, 데이터, 힙) 초기화의 무거운 작업이 진행됩니다.
캐쉬메모리 초기화란,
쉽게말해 대면수업을 들을 때 다른 사람의 노트북을 사용하지 않고, 저희 각자의 노트북을 가져와 사용하는 거라고 생각하시면 됩니다.
왜냐하면 본인 노트북에 지금까지 본인 방식대로 정리한 자료들이 있을테니까요!
이렇듯,
프로세스는 각각 독립된 메모리영역을 할당받기 때문에 프로세스 사이에서 공유하는 메모리가 없어
컨텍스트 스위칭이 발생하면 캐쉬에 있는 모든 데이터를 모두 리셋하고 다시 캐쉬 정보를 불러와야 합니다.
두번쨰론,
프로세스는 독립된 환경에서 실행되기에 프로세스간에 공유해야 할 데이터가 생기면 프로세스 사이의 통신을 구축해줘야 하는데,
이를 'IPC' 라고 불러요.
공유메모리를 두거나, 파일, 파이프 등등 프로세스 간의 통신을 위한 기술로 프로세스끼리 통신해야 하는데
'IPC'를 유지하는 비용과 프로세스를 전환하는 비용이 멀티 프로세싱의 단점이죠.
여기서 중요한 용어가 나왔어요. 바로 IPC 입니다.!
IPC란 Inter Process Comunication(인터 프로세스 커뮤니케이션)의 약자로 프로세스 간 통신을 말하며
즉, 하나의 컴퓨터 안에서 실행중인 서로 다른 프로세스 간에 발생하는 통신을 IPC 라고 부르죠.
위의 그림처럼 우리가 사용하는 프로세스들은 모두 유저공간에서 개별로 OS로부터 할당받은 독립된 공간에서 운행중에 있습니다.
방금 말씀드린것처럼 프로세스는 독립된 공간에서 운행중이다보니 서로간에 통신이 어렵다는 단점이 있어요.
이걸 해결하기 위해 커널 영역에서 IPC라는 프로세스들 간에 통신을 제공하고 있는 겁니다.
이처럼 프로세스들은 커널이 제공하는 IPC기술을 통해 프로세스간에 통신을 할수 있습니다.
이번엔 프로세스의 특성에 대해 알아볼게요.
프로세스 동시성, 프로세스 병렬성 또는 이둘의 혼합으로 표현할수 있습니다.
먼저 동시성의 개념은,
프로세서(CPU)가 여러가지 작업이 동시에 실행되고 있는것처럼 구현되는 것인데요.
서로 독립적인 작업을 작은 단위의 연산으로 나누고 시간 분할 형태로 연산하여 논리적으로 동시에 실행되는것처럼 보여주는 것을 말합니다.
한번에 많은 것을 처리하고, 논리적인 개념이기 때문에 단일 스레드에서도 사용이 가능한 개념이예요.
그리고 동시성 동작 방식은 빠르게 전환하며 여러 작업을 수행하여 동시에 여러 작업이 실행되는것처럼 보이는 것인데
이때 다른 작업으로 바꿔서 실행할 때 내부적으로 컨텍스트 스위칭 이라는게 일어납니다.
CPU는 한번에 한 개의 프로세스만 처리가 가능합니다.
우리 눈에는 여러 개의 작업이 동시에 실행되는 것처럼 보일지 몰라도 CPU는 계속해서 특정 업무를 처리하는 프로세스들을 바꿔주는 일을 내부적으로 진행하고 있어요.
즉, 이렇게 현재 진행중이던 프로세스의 지금까지의 연산결과, 혹은 어디까지 진행되었는지 이러한 정보들을 PCB에 저장하고 이제 실행되려는 프로세스에게 cpu를 할당해 주어야 합니다.
이렇게 하나의 프로세스에 대한 정보들을 저장해 놓고 새로운 프로세스에 대한 정보를 가져오고 메모리를 할당해주는 이러한 과정을 컨텍스트 스위칭(문맥교환) 이라고 합니다.
설명한 내용중에서 'PCB' 라는 용어가 처음 나왔는데 잠시 짚고 넘어가자면,
특정한 프로세스를 관리할 필요가 있는 정보를 포함하는 운영체제 커널의 자료구조를 말하며
그정보에는 프로세스 번호, 포인터, 프로세스 상태, 레지스터, 프로그램 카운터(코드 위치) 등이 있습니다.
또, PCB는 프로세스 생성시 만들어지며 주기억장치에 유지됩니다.
이렇게 들으면 사실 이해하기 어려울수 있습니다.
그렇다면,
이부분에 대해 좀더 쉽게 접근해 볼까요?
우린 인터넷을 하고 있어요.
그리고 인터넷을 하면서 음악도 듣고 채팅도 할 수 있어요.
어떻게 컴퓨터는 이 많은 일을 동시에 할 수 있을까요?
사실 우리는 이걸 동시에 처리한다고 느끼지만 실상 컴퓨터는 동시에 처리하지 않아요.
Time sharing 이라고해서 짧은시간동안 왔다갔다 번갈아서 재빨리 처리해주는건데 그 방법이 아주 효율적이고 빨라서 우리가 느끼지 못할뿐입니다.
이게 가능한 이유는 운영체제라는 프로그램 덕분이고, 이렇게 프로세스들이 교체되어 수행되고나면 다시 다른 프로세스를 불러와야하는데
이말은 이전 작업에 대한 내용을 기억하고 있다는 얘기가 돼요.
프로세스 단위로 정보를 저장해주는 block이 있는데 이게 바로 PCB 입니다.
다음은 병렬성입니다.
병렬성의 개념은, 동시성과 다르게 물리적으로 실제로 동시에 여러 작업을 연산하는 것을 말합니다.
때문에 단일 스레드에선 사용이 불가능하고 다중 스레드가 필요하죠.
그리고 물리적인 개념입니다.
또한, 병렬성은 사용방법에 따라 '데이터 병렬성'과 '작업 병렬성'으로 나눌수 있는데,
'데이터 병렬성'은 하나의 단일 작업을 여러 개로 쪼개서 연산하는 것을 말하고,
'작업 병렬성'은 독립적인 작업을 각 스레드에서 담당하여 연산하는 것을 말합니다.
동시성과 비교해서 말하면, 우선 동시성은 동시에 실행되는것처럼 보이지만, 병렬성은 실제로 동시에 여러 작업이 처리되는겁니다.
혼합은 동시성의 특성과 병렬성의 특성을 혼합하여 진행합니다.
네 안녕하세요!
이어서 발표 진행할 김남수입니다.
지금까지 서이님 발표 다들 집중해서 잘 들어주셨죠??!
끝까지 집중 부탁드릴게요!
그럼 다음 주제인 스레드에 알아보겠습니다!
스레드란?
프로세스 내에서 실행되는 여러 흐름의 단위,
프로세스가 할당받은 자원을 이용하는 실행의 단위입니다.
스레드의 종류에는 두가지가 있는데요.!
싱글스레드와 멀티스레드 이렇게 종류가 나뉘어 있습니다.
싱글스레드는 말 그대로 프로세스 내에 메인스레드 하나만이 존재하여,
독립적으로 순차 실행하는겁니다.
멀티스레드는 하나의 프로세스에서 여러 개의 스레드가 병행적으로 실행되는겁니다.
다음으로 스레드의 특징 짚어드리겠습니다.
스레드는
프로세스 내의 주소공간 뿐만 아니라,
프로세스가 할당받은 메모리를 프로세스 내에서 Code, Data, Heap 영역을 공유하는 특징이 있습니다.
남은 Stack영역은 각자 할당받기 때문에 이 영역은 공유할 수 없습니다.
이 점만 봐도 프로세스와 큰 차이점이 느껴 지시겠죠??
멀티스레드는
하나의 프로세스를 여러개의 스레드로 구성하고,
각 스레드로 하여금 하나의 작업을 처리하도록 하는것입니다.
자, 서이님께서 먼저 좋은 예시로 여러분들의 이해를 도운 것처럼,
저도 서이님 흉내를 한 번 내보겠습니다.
TMI지만,
제가 또 호텔리어 출신이기 때문에,
호텔을 예로 들어보겠습니다.
자,
한 고객님꼐서 호텔을 방문했습니다.
그 고객님은 호텔 안에 수영장에서 수영을 너무나 재밌게 한 나머지 뱃가죽이 등에 붙어 본인이 방에 쏜살같이 올라가서 햄버거를 주문했습니다.
이 주문을 받은 인룸다이닝 부서 직원들은 햄버거를 맛있게 요리해서 딜리버리를 완료했겠죠??
여기서 이 부서 직원들의 재능은 각각 다를겁니다.
모든 사람들이 다 다른것처럼
A직원은 사람들과의 소통에 능하고,
B직원은 요리를 잘하고,
C직원은 길눈이 밝다고 해보겠습니다.
이 세 직원들은 당연히 빨리 승진을 하고 싶을거고, 일을 잘해야되기 때문에 일의 과정이 완벽하게 적힌 부서의 가이드라인을 서로 공유를 할것이고, 본인들의 재능을 사용할 수 있는 일들을 할겁니다.
A직원은 주문전화를 받고,
B직원은 햄버거를 요리하고,
C직원은 고객님의 방까지 음식을 딜리버리 하겠죠?
여기서
인룸다이닝 부서를 프로세스
부서의 직원을 스레드
직원들의 각각의 재능을 Stack영역
부서의 가이드라인을 Stack을 제외한 나머지 메모리 영역이라고 생각하시면
지금까지 말씀드린 스레드와 멀티스레드 이해 되시겠죠?!
인룸다이닝 부서에 직원이 한 명 밖에 없다면...
그 고객님은 아사하셨을 겁니다...ㅠ
자 이제 거의 다 끝나갑니다.! 조금만 더 저의말에 귀를 귀울여주세요!
다음으로는,
멀티스레드의 장단점 간략하게 설명드릴게요!
장점으로는,
프로세스를 생성하여 자원을 할당하는 일명 '시스템 콜'이 줄어들어
자원을 효율적으로 관리 할 수 있고요,
스레드간에 데이터를 주고받는 것이 프로세스보다 간단해지고, 스레드사이의 작업량이 작아 Context Switching이 빨라져서 시스템 처리량이 증가합니다.
마지막으로 앞서 말씀드린 예시처럼
스레드는 프로세스 내의 Stack영역을 제외한 모든 메모리를 공유하기 떄문에 프로그램 응답 시간이 단축되는 장점이 있습니다.
단점으로는,
프로세스와는 다르게 하나의 스레드에 문제가 발생하면,
전체 프로세스가 영향을 받습니다.
왜냐하면, 스레드끼리 Stack영역을 제외한 모든 메모리를 공유하기 때문이겠죠?
그리고 스레드 간의 자원공유는 전역변수를 이용하는데요,
함꼐 사용할 때 충돌이 발생할 수 있답니다.
또한,
일명 디버깅이라고 하는 프로그램 개발 단계 중에 발생하는 시스템의 논리적인 오류나 비정상적인 연산을 찾아내,그 원인을 밝히고 수정하는 작업 과정 까다롭습니다.
그래서 주의 깊은 설계가 필요합니다.
프로세스와 스레드가 무엇인지 다들 완벽하게 이해하셨길 바라며,
저희의 발표를 마치고요,
혹시 질문 있으실까요?
없으시면,
여기서 발표 마무리 하겠고요,
추가적으로
저희의 발표를 듣고 프로세스와 스레드에 대해 이해가 안된 분들은 없을거라고 생각하지만, 혹여나 파리의 똥만큼이라도 이해가 부족하다면 저희 조원들 찾아 연락 주십시오.
감사합니다!