프로세스는 뭐고 스레드는 뭔가요?

프로세스는 뭐고 스레드는 뭔가요?
제가 웹 서핑을 하다가 마음에 드는 게임을 찾았어요.
그래서 다운로드 버튼을 눌렀는데 갑자기 마우스가 안 움직이고 키보드도 안 먹힙니다.
몇 분에 걸쳐 이 게임이 다 다운받아질 때까지 컴퓨터가 먹통이 되어있는 거죠.
아니 무슨 이런 컴퓨터가 있냐고요?
옛날 컴퓨터들은 이런 식이었습니다.
게임을 다운로드하는 작업, 마우스나 키보드로부터 입력을 받는 작업, 브라우저로 사이트를 돌아다니는 작업,
이들을 동시에 하지 못하고 한 번에 하나씩만 할 수 있었기 때문이죠.
컴퓨터가 프로세스 여러개를 함께 돌리는 '멀티테스킹'이 가능해지기 전까지는요.
Process & Thread
여러분의 컴퓨터에서 실행할 수 있는 파일, 윈도우의 경우 이름 뒤에 .exe 붙어있는 그런 파일들을 '프로그램'이라고 합니다.
그리고 그 프로그램이 실행돼서 돌아가고 있는 상태, 즉, 컴퓨터가 어떤 일을 하고 있는 상태를 프로세스라고 합니다.
위와 같은 상황과 달리 오늘날처럼 쾌적하게 컴퓨터를 사용할 수 있는 건, 운영체제가 여러 개의 프로세스를 함께 돌리고 있기 때문입니다.
윈도우를 쓰고 계신다면 지금 당장 Ctrl + Alt + Del 키를 누르고 작업관리자로 진입하셔서
내 컴퓨터에 얼마나 많은 프로세스들이 지금도 열심히 돌고 있는지 확인하실 수 있습니다. 여러 프로세스를 함께 돌리는 작업은 동시적, 병렬적 또는 이 둘의 혼합으로 이루어져 있습니다.
동시적(Concurrency) Process
동시성은 프로세서 하나가 이거조금하고, 저거쪼금하고 또 다른거 조금하고, 이렇게 여러 작업을 돌아가면서 일부분씩 진행하는 겁니다.
이렇게 진행중인 작업을 바꾸는 걸 Context({}) Switching이라고 하는데, 여기에도 다양한 방식과 알고리즘이 쓰입니다.
이 과정이 엄청 빨리 돌아가니까 사람에게는 이 프로세스들이 마치 동시에 진행되는 것처럼 느껴지는 겁니다.
병렬적(Parallelism) Process
병렬성은 프로세서 하나에 코어 여러개가 달려서, 각각 동시에 작업들을 수행하는 겁니다.
듀얼 코어, 코드 코어, 옥타 코어, 이런 명칭이 붙는 멀티코어 프로세서가 달린 컴퓨터에서 할 수 있는 방식입니다.
CPU의 속도가 발열 등 물리적 제약 때문에 예전만큼 빠르게 발전하지 못하자 그 대안으로 코어를 여러개 달아서
작업을 분담할 수 있도록 만든 겁니다.
컴퓨터는 이렇게 여러 개의 프로세스를 한번에 돌릴 수 있게 되었습니다.
하지만, 이걸로 충분할까요?
아까 말씀드린 브라우저도 하나의 프로그램이고, 브라우저가 실행되면서 하나의 프로세스가 진행되고 있죠.
그런데 브라우저가 일을 할 때(게임을 다운로드 받는 동시에)도 다른 페이지들을 돌아다닐 수 있어야 하고,
유튜브 영상의 데이터를 받아오면서 받아진 데이터로 영상을 재생할 수도 있어야 하죠.
한 프로세스 안에도 여러 갈래의 작업들이 동시에 진행될 필요가 있는 겁니다.
이 갈래를 Thread 라고 부릅니다.
Thread
프로세서 - 요리사
대량 주문이 들어오는 식당에서 끊이없이 만들어내는 요리 하나하나
  • 라면 끓이기
  • 김밥 말기
  • 햄버거 만들기
이것들이 프로세스입니다.
컴퓨터는 프로세스마다 자원을 분할해서 할당합니다.
라면끓이는 섹션, 김밥 마는 섹션, 햄버거 만드는 섹션, 이렇게 조리공간을 나눠서 요리사 혼자 돌아다니면서 동시적으로 하든
여럿이서 병렬적으로 하든,
혹은 이 둘을 섞어서 하든, 이 메뉴들을 계속해서 만들어 내는 거죠.
햄버거를 만드는 프로세스에서는 패티를 굽는 스레드가 진행되는 동안, 빵에 야채를 얹고 소스를 뿌리는 스레드도 진행될 수 있겠죠.
한 메뉴의 스레드들은 같은 조리대에서 진행됩니다.
패티는 다른 프로세스에서 굽고 야채는 이 프로세스에서 얹는다면 같은 조리대에서 작업하는 것보다 일하기가 훨씬 힘들겠죠.
같은 메뉴를 만들 때는 같은 공간과 장비, 즉 컴퓨터의 같은 자원을 공유하는 것이 더 효율적일 겁니다.

프로세스들은 컴퓨터의 자원을 분할해서 쓰지만
스레드는 프로세스마다 주어진 전체 자원을 함께 사용하는 겁니다.
이게 속도와 효율 면에서는 낫겠지만 단점도 있습니다.
스레드 단점
프로세스 안에서 공유되는 변수에 스레드 두개가 동시에 손을 댑니다.
Error가 발생할 겁니다.
어떤 버튼을 누를 때마다 숫자가 1씩 증가합니다.
스레드 둘이 이 버튼을 열번씩 누르면 결과물은 20이 나와야하는데, 그보다 적은 숫자가 나와버립니다.
둘이 버튼을 동시에 누르는 경우에는 숫자가 1만 올라가기 때문입니다.
시간문제들로 발생하는 이러한 문제들을 예상하고 방지해야 하기 때문에 스레드를 사용하는 프로그램들은 코드를 짜기도,
디버깅을 해서 오류를 찾아내고 원인을 밝히기도 굉장히 까다로운 경우가 많습니다.

다행히도 이러한 작업들을 더 쉽고 안전하게 할 수 있는 도구들이나 프로그래밍 방식들이
(Closure, Lambda, Actor, Functional Programming ...)
오늘날의 개발자들을 많이 도와주고 있습니다.