이전에 한번 프로세스와 쓰레드를 다룬 적이 있었는데 이번 수업을 들으면서 많이 부족하다고 생각이 들어 직접이해하면서 다시 정리해보려고 한다.
Inpa Dev
수업 내용을 포함하여 이분의 블로그를 참고해서 한번 제대로 파보았다
프로세스가 작업의 단위이고 스레드가 실행흐름의 단위 라는 것만 한번 기억해보자
*.exe
파일이나 *.dmg
파일과 같은 컴퓨터에서 실행할 수 있는 파일을 통칭하는 것이 프로그램이다.
이런 프로그램들을 실행하지 않은 상태일 때 바로 정적 프로그램이고 이걸 줄여서 프로그램이라고 부른다.
이전 포스팅에서 작성한 컴파일 부분에서 정적언어의 컴파일 완료후 exe
파일이 생성되고 이걸 목적 프로그램이라고 작성한 부분도 있었다
프로세스는 프로그램을 실행 시켜서 정적인 프로그램 상태를 동적으로 변하게 만들어 프로그램이 동작하고 있는 상태를 말한다.
즉, 컴퓨터에서 작업중인 프로그램!이다
블로그를 참고하며 보는데 실제로 우리가 가끔 크롬이든 카카오톡이든 이런 프로그램들을 실행하다가 멈추거나 렉이 걸리면 강제 종료하기위해 작업 관리자를 열어 작업 끝내기를 한다.
이때 보면
작업 관리자 탭에 프로세스 부분을 확인 할 수 있는데 이 모든게 현재 동작하고 있는 프로그램 들이다.
근데 여기서 의문점을 가진다. 프로그램들이 동작하고 잇는 프로세스 들인데 모두 메모리를 지니고 있으며 어던것들은 cpu가 0%인데 지금 내가 작성하고 있는 이 벨로그를 띄우고 잇는 구글 크롬은 cpu가 들락날락 거리고 있다
의문점이 생긴다.
참고한 블로그의 추가 설명들을 살펴보며 이해해보자
여기서 작업 관리자에 있는 모든 프로세스들이 아주 조금이라도 메모리를 가지고 있는지 이해가 된다.
os는 물론이고 우리가 사용하기 위해 열심히 일한 프로세스 들은 기본적으로 실행하기 위해 메모리 공간을 할당받아야 하기 때문에 각자 조금이라도 메모리를 가지고 있는 것이다
프로그램과 프로세스는 같은 게 아닌가요? 할 수 있는데 다르다. 프로세스는 실행되어 작업중인 컴퓨터 프로그램이고 프로그램은 어떤 작업을 하기 위해 실행할 수 있는 파일이다.
엄연히 다르다.
또 프로그램은 메모리에 올라가 있지 않고 디스크에만 있는 정적인 상태고 프로세스는 메모리에 적재되고 cpu에서 자원을 할당받아 프로그램을 실행되고 있는 동적인 상태이다
그럼 cpu는 왜 다른애들은 0퍼센트인데 크롬은 들락날락 하나요? 는 다른 개념들을 채우고 와서 한번 확인해 보자
과거엔 프로그램을 실행할 때 프로세스 하나만을 사용해서 이용했다
지금 보면 컴퓨터는 진짜 엄청난 발전을 했는데 내가 어릴적만 해도 컴퓨터실에는 뚱땡이 모니터에 사양도 구려서 너구리 같은 게임을 하고 했는데 현재는 1.5키로 짜리 노트북에 손가락 반마디도 안되는 두께의 노트북으로 작업을 하고 다닌다.
이처럼 기술이 발전됨에 따라 프로그램이 복잡해지고 다채로워 졌는데 프로세스 작업 하나만을 사용해 프로그램을 실행하기에는 한계가 생기기 시작했다
우리는 카톡을 하면서 크롬 블로그에 글을 쓰고 슬랙도 사용하고 그 와중에 필요한 파일이 있으면 다운로드도 한다. 프로세스 하나만이라며 어떻게 가능할까?
여기서 탄생한게 쓰레드이다
스레드는 하나의 프로세스 내에서 동시에 진행되는 작업갈래, 흐름의 단위를 말한다
우리가 크롬 브라우저를 실행한다 하면 크롬 브라우저라는 프로그램이 실행되며 하나의 프로세스가 생성될 것이다.
우리는 그럼 브라우저로 한가지만 할까? 브라우저에서 파일도 다운받고 쇼핑도 하고 검색도 하고 여러가지를 한다.
즉, 이런 하나의 프로세스 안에서 여러가지 작업의 흐름들이 동시에 진행되기 때문에 가능한 것인데, 이러한 일련의 작업 흐름들을 스레드라고 한다. 만약 여러개가 있다면 이를 멀티(다중)스레드라고 부른다.
만약 스레드 수가 많을 수록 프래그램도 동시에 하는 작업이 많아져서 성능이 올라간다
프로세스에서의 스레드를 표현한 그림인데 하나의 프로세스는 반드시 하나 이상의 스레드를 가지고 스레드가 그 이상 되는 것은 프로그램을 개발한 개발자가 직접 프로그래밍 해서 위치 시켜주어야 한다.
그럼 이제 내부 작동 방식으로 더 가보자
프로세스가 만들어지면 우리가 알고있는 4가지의 메모리영역이 구성되어서 할당 받게 된다
CODE / DATA / STACK / HEAP
stack과 heap영역은 선언할 때 그 크기가 결정되는 정적영역인 code,data와 다르게 프로세스가 실행되는 동안 크기가 동적으로 변하는 영역이다
스레드는 프로세스가 할당 받은 자원을 이용하는 실행단위로 스레드가 여러개 있기 때문에 우리가 브라우저에서 여러가지 일을 동시에 할 수 있는 것이다.
또 스레드끼리 자원을 공유하며 프로세스 실행 흐름의 일부가 되기 때문에 동시 작업이 가능한 것이다
이때 스레드는 프로세스의 4가지 메모리 영역중 stack만 할당받아 복사하고 나머지 영역들은 다른 스레드들과 공유되는데 이로인해 각각의 스레드는 별도의 stack을 가지고 있지만 heap 메모리는 고유하기 때문에 서로 다른 스레드에서도 가져와서 읽고 쓸 수 있게 된다
여기서 왜 스택만 가지고 있을까? 하는 고민을 바로 블로그에서 참고할 수 있는데
stack 영역은 함수 호출 시 전달되는 인자, 되돌아갈 주소값, 함수 내에서 선언하는 변수 등을 저장하는 메모리 공간이기에 독립적인 스택을 가졌다는 것은 독립적으로 함수 호출이 가능하다라는 의미이다.
그렇기에 독립적인 실행 흐름을 가지게 되는데 즉, stack을 가짐으로써 스레드는 독립적인 실행 흐름을 가지게 되는 것이다.
하지만 프로세스는 다른 프로세스의 메모리에 직접 접근할 수는 없다.
근데 의문이 든다. 위에서 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없다고 했지만 우리가 여러 프로그램들을 같이 사용하며 정보를 주고 받고 한다.
그럼 어떻게 정보를 공유할까?
하지만 프로세스 자원 공유는 단수히 CPU 교체뿐만 아니라 RAM과 CPU사이의 캐시 메모리까지 초기화 되기에 자운부담이 크다는 단점이 있다.
그래서 다중작업이 필요한 경우 스레드를 이용하는 것이 훨씬 효율적!
동시에 여러가지 일을 하는 이런 멀티태스킹 기술인데 그냥 CPU 프로세서가 프로그램들을 한꺼번에 동시 실행한다 생각하겠지만 , 내부적으로 복잡한 원리에 의해 처리된다.
그리고 이 원리가 OS이론의 핵심 원리이다.
이번 데스크탑도 스스로 알아보고 주문하고 조립한 데스크탑인데 CPU를 주문할 때 항상 보이는 몇코어에요? 스레드는? 이런 것들이 있다
CPU 한개는 여러개의 코어를 가질수 있는데 이전에 다뤘던 컴퓨터 아키텍처, ALU CU 레지스터 이런게 다 담겨있어서 명령어를 해석하고 실행하는 반도체 유닛을 바로 CPU 코어 유닛이라고 한다.
만약 4코어 8스레드라고 한다면 물리적 코어 하나가 스레드 두개 이상을 동시 실행할수 있따는 의미가 되는데 즉, 운영체제가 8개의 작업을 동시에 처리할 수 있다는 뜻이다.
이걸 하이퍼 스레딩 기술이라고 한다.
다만 우리가 알고 지나가야 할 것은 CPU에선 하드웨어적인 스레드고 지금 배운 개념은 소프트웨어적인 스레드이다. 둘은 다르다는 걸 인지하자
근데 아까도 봤다싶이 백그라운드 프로세스만 몇십개에 지금 내가 실행하고 있는 프로세스들을 다 합하면 몇십 몇백개가 되기도 할 텐데.. 그럼 8개의 스레드로 가능한 일일까?? 싶다.
이걸 이해하기 위한 개념을 알아보자
병렬성은 직관적으로 명령어를 뽑아 해석하고 실행하는 반도체 유닛인 여러개의 코어에 맞춰 여러개의 프로세스, 스레드를 돌려 병렬로 작업들을 동시 수행하는 것으로 멀티 코어 프로세서가 달린 컴퓨터에서 할수 있는 방식이다
즉 실제로 동시에 여러작업이 실행되고 있는 것으로 물리적으로 한번에 많은 것을 처리하고 있는것이다.
예시도 쉬운데 그냥 2가지 주문이 들어왔고 우리는 2명의 일할 직원이 있으니 그냥 각자 1개씩 주문 처리를 하면 된다.
둘 이상의작업이 동시에 실행되는 것을 의미하는데 이 '동시'라는 의미가 병렬성에서 말한 동시랑 헷갈릴 수 있다. 단어가 똑같지 않냐? 할수 있지만 실제로는 병렬성(Parallelism)이 정말 동시에 실행하는 것이라고 하면 동시성(Concurrency)은 동시에 실행하는 것처럼 보이게 하는 것이다.
위 병렬성 예시를 그대로 들어보자면 4가지 주문이 들어왔는데 나 혼자 일하고 있는 상태로 4가지 주문을 동시에 처리하기 위해 1번 조금하고 2번 조금하고 3번 조금 하고 이걸 무지하게 빠르게 하고 있어서 옆에서 보면 와 4개를 동시에 만드시네? 할 수 있는 것이다.
이때 작업들을 번갈아 실행할 때는 아주 잘게 나누어서 조금씩 작업하는에 이유는 사용자에게 더 빠른 반응성을 제공하기 위해 동시에 처리되는 것처럼 보이게 하기 위해서다.
그래서 이렇게 진행중인 작업들을 번갈아 바꾸는 것을Context Switching 이라 부른다!
중요한 개념이다 Context Switching
그럼 동시성은 그저 동시에 돌아가는 것처럼 보일 뿐 실제로 동시에 돌아가는 것은 아니기때문에 최종 작업에 걸리는 시간은 별로 차이가 없을것이다.
병렬성은 진짜 동시에 실행하는 것이기에 시간이 엄청 줄어들텐데 말이다.
하드웨어적 한계가 첫번째로 있다
CPU 발열 때문에 성능을 올리기엔 한계가 봉착되었고 코어의 성능을 올리는 대신 코어를 여러개 탑재하여 쿼드 코어, 옥타 코어 등의 CPU들이 출시되고 있찌만 아무리 코어를 많이 넣어도 수십개를 넣을 수는 없고 하드웨어적인 제한이 걸리니 수십 수백개의 프로세스를 돌리기 위해 동시성이 필요한것이다.(사용자의 더 빠른 반응성을 제공하기 위해서라고 위에서도 한번 나왔다)
논리적인 효율이 2번째이다.
4코어 8스레드 환경에서 16개의 작업이 있다라고 했을 때 8개가 오래걸리는 작업이고 다른 8개는 짧은 작업이다.
8스레드 환경이니 최대 8개까지 동시에 실행할 수 있을텐데 만약 오래걸리는 8개의 작업이 먼저 시작되었다면 나버지 짧은 8개의 작업들은 금방 끝낼 수 있음에도 불구하고 오래걸리는 8개의 작업을 기다려야만 한다
이런 비효율적인 면을 극복하기 위해! 작업을 아주 잘게 나눠 번갈아 가면서 처리하는 동시성 개념을 채택한 것이다!
고로 최대 8개 작업에 대해서 8개의 논리적인 스레드가 병렬적으로 빠르게 동시적으로 작업을 하며 그보다 많은 수십개의 소프트웨어적 스레드가 있따면 병렬성과 동시성을 섞어 동시에 돌리게 된다.
프로세스와 스레드는 각각 생명주기를 가지고 있고 운영체제는 이런 생명주기를 관리하고 조정하여 시스템 자원을 효율적으로 사용할 수 있게 해준다
운영체제에서 CPU를 사용할 수 있는 프로세스를 선택하고, CPU를 할당하는 작업
프로세스 스케줄링은 프로세스 우선순위, 작업량 등을 고려해서 효율적으로 배치하고 이를 통해 운영체제는 CPU를 효율적으로 사용해서 시스템 성능을 향상시킨다.
그렇기에 스케줄링이 멀티 태스킹 작업을 만들어내는 데 있어 핵심적이다.
프로세스가 생성되서 실행하기 까지는 여러 상태를 가지는데 상태의 변화에 따라 프로세스가 동작한다.
프로세스가 실행되는 동안 상태가 os에 의해 변경되는 것인데 os는 프로세스의 상태를 감시하고 프로세스 상태를 기반으로 스케쥴링을 통해 관리 제어한다.
ready중인 프로스세중에 어떤걸 running상태로 바꿀찌 등
상태가 바뀔 때를 표현한 것은
일단 아까 한번 나온 중요한 개념인 컨텍스트 스위칭은 CPU가 한 프로세스에서 다른 프로세스로 전환할 때 발생하는 일련의 과저으로 위의 동시성 파이트에서 다뤘듯 CPU는 한번헤 하나의 프로세스만 실행할 수 잇으니 여러개의 프로세스를 번갈아가며 실행해 CPU 활용률을 높이는 것이다
구체적으로 본다면 동작중인 프로세스가 대기를 하면서 해당 프로세스 상태(Context)를 보관하고 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업!
스위칭이 일어날때 다음 프로세스는 위에서 말한 스케줄러가 결정하게 된다
os에서 프로세스를 관리하기 위해 해당 프로세스의 상태 정보를 담고 있는 자료구조
프로세스를 컨텍스트 스위칭 할때 지금까지 했던 작업을 기억해야 또 다시 불러왔을 때 바로 이어서 할 수 있으니 현재 상태를 어딘가에 저장해야한다. 즉, PCB는 프로세스 스케줄링을 위해 프로세스에 관한 모든 정보를 저장하는 임시 저장소
프로세스가 생성되면 메모리에 해당 프로세스의 PCB가 함께 생성되고 종료시 삭제된다
일반적으로 pcb의 내부는 아래와 같은 정보들을 포함하고 있다(운영체제마다 다를수 있음!)
동작만 간단하게 살펴보자면
컨텍스트 스위칭으로 우리는 빠른 반응성과 동시성을 얻지만 프로세스가 변경되는 과정에서 프로세스의 상태, 레지스터 값등이 저장되고 불러오는 등의 작업이 수행되기 때문에 많은 부담을 주게된다.
위의 과정 스샷을 보면 곧바로 이어져서 스위칭이 이루어져 실행되는 것이 아닌 약간의 뜸이 있다.
이 간극이 바로 컨텍스트 스위칭 오버헤드 이다.
어쨋든 프로세스가 아예 다른 것이기에 PCB 저장 및 복원을 할 때, CPU 캐시 메모리 무효화, 프로세스 스케줄링 비용 등이 다 산출되는 것이다.
자 그럼 프로세스에서의 컨텍스트 스위칭이 많이 일어나면 일어날수록 효율이 나빠진다는 것을 볼 수 있다. 그럼 쓰레드는 어떨까?
운영체제에서 다중 스레드를 관리하고 CPU를 사용할 수 있는 스레드를 선택하고 CPU를 할당하는 작업
프로세스 스케줄링과 다른점은 하나의 프로세스 내에서 다수의 스레드가 동작하는 형태이기에 스레드간 상호작용과 동기화 문제를 고려해야 한다.
프로세스처럼 스레드도 상태가 있는데 4가지가 있다
멀티 스레딩 환경에서 스레드 간의 실행을 전환하는 기술로 프로세스의 컨텍스트 스위칭과 다른점은 스레드 컨텍스트 스위칭은 하나의 프로세스 내의 스레드들을 교환한다는 점이다
무슨말인가?
다른 글들을 참고하니 이해가 됐다. 즉 캐시 메모리등 프로세스 컨텍스트 스위칭은 아예 프로세스가 뒤바뀌는 것이기에 많은 것이 부담되는데 쓰레드는 하나의 프로세스 안에서 각자 STACK 영역만 독립적으로 가지고 있지 많은 부분을 공유하고 있기 때문에 캐시메모리 초기화등을 거치지 않아서 훨씬 부담이 적고 빠르게 가능한 것이다.
각 스레드마다 os에서 유지하는 스레드에 대한 정보를 담고있는 자료구조인데 TCB는 PCB안에 들어있다.
뭐 굳이 따로 생각안해도 스레드 자체가 프로세스 안에 있는 놈인데 당연하다
PCB와 마찬가지로 뭐 상태 정보, ID 우선순위 등 다양한 정보가 들어있으며 스레드가 생성될 때 운영체제에 의해 생성되고 실행을 마치고 소멸될 때 함께 소멸한다
또한 스레드 간의 자원공유와 동기화도 TCB를 사용해 관리된다
둘 다 멀티 태스킹 환경에서 여러 프로세스나 스레드를 동시에 실행하기 위한 기술이지만 차이점은 있다
그냥 쉽게 보면 한 어플리케이션에 대한 처리방식이고 여러개의 프로세스,스레드가 동작하는 것이다.
프로세스와 스레드가 단일이 아닌 다중으로 돌아가게 하는 것이다. 장단점은 있다
Reference
시니어코딩 - 풀스택 실무 프로젝트 5기
완전히 정복하는 프로세스,스레드