AI가 이렇게 발전하는데 이거 왜 공부해야함? - 프로세스와 스레드
0. 난 어디까지 공부해야 할까 (공통)
AI가 발전하면서 어떤 것을 공부해야 하고 얼마만큼 깊이 공부해야 할지 모르겠다.
그래서 GPT 에 물어봤다.
"AI가 이렇게 발전하는데, 다 해주는데, 이런 시대에서 개발자로서 살아남으려면 난 어떤 걸 공부해야 하지? "
강의나 유튜브에서나 그렇듯 비슷한 얘기를 꺼낸다.
AI가 코드를 만들어낼 수는 있어도 책임지는 것은 사람이다.
이 지식들은 구현을 위한 것이 아니라 진단, 판단, 검증, 결정을 위한 지식이다.
그렇게 제안해준 커리큘럼으로 하나씩 정리하면서
왜 이 지식들은 AI가 발전해도 필요할까를 알아볼 생각이다.
그 첫 번째 주제가 프로세스와 스레드.
1. 들어가며
공부하기전에 프로세스와 스레드에 대해 물어본다면
나는
프로세스는 실행 중인 프로그램이고 프로세스끼리 독립적이다.
스레드는 프로세스 내부의 실행 단위이고 스레드끼리는 프로세스 내의 자원을 공유한다.
이렇게 말할 것 같다.
정확한 표현인지는 모르겠다.
나는 작은 프로젝트를 세 번 정도 진행하면서
프로세스와 스레드라는 개념이 직접적으로 필요하다고 느낀 적이 거의 없었다.
그것은 나의 깊이와 경험이 부족했던 것이기에
왜 이 개념이 중요한지 이번에 확실히 공부를 해봐야겠다.
2. 프로그램, 프로세스, 스레드
2-1. 프로그램
- 보조저장장치에 있는 명령어와 데이터들의 집합, 아직 실행되지 않은 정적인 상태
보조저장장치 - SSD, HDD와 같은 컴퓨터가 꺼져도 저장되는 저장장치
2-2. 프로세스
- 프로세스는 운영체제로부터 메모리와 필요한 자원을 할당받아 실행 중인 프로그램이다.
- 프로세스는 자신만의 메모리 공간을 가진다. 기본적으로 프로세스끼리 메모리를 직접 공유하지 않는다.
메모리 - 주기억장치인 RAM을 말한다. 컴퓨터가 꺼지면 데이터가 휘발되는 저장장치
자원 - 메모리, 파일, CPU 실행시간 등 실행에 필요한 요소들
2-3. 스레드
- 프로세스 안에서 실제 작업을 수행하는 실행 흐름의 단위이다.
- 프로세스가 할당받은 자원을 이용해 실제 명령을 수행한다.
- 같은 프로세스의 스레드들은 코드, 데이터, 힙 영역을 공유하고, 각자 별도의 스택을 가진다.
3. 프로세스 vs 스레드
| 자원 | 실행 흐름 | 통신 | 안정성 | 생성 비용 | |
| 프로세스 | 독립된 메모리 공간 | 프로세스끼리 독립적 | 프로세스끼리 IPC 같은 별도 통신 방식 필요 | 한 프로세스가 죽어도 다른 프로세스에 영향이 적음 | 프로세스 생성 및 컨텍스트 스위칭 비용이 스레드보다 크다. |
| 스레드 | 같은 프로세스 내부 자원을 공유 | 같은 프로세스 안에서 여러 실행 흐름을 가짐 | 같은 메모리를 공유하므로 통신이 비교적 쉬움 | 한 스레드의 문제가 같은 프로세스 전체에 영향을 줄 수 있음 | 상대적으로 가벼움 |
IPC - Inter-Process Communication 프로세스 간 통신 (ex 파이프, 메시지 큐, 공유 메모리, 소켓 등)
컨텍스트 스위칭 - 현재 실행 중인 실행 흐름의 상태를 저장하고, 다른 실행 흐름의 상태를 복원하는 것
4. 멀티프로세스 vs 멀티스레드
| 장점 | 단점 | |
| 멀티프로세스 | - 안정성 높음 - 독립성 높음 |
- 자원 사용량 큼 - 통신 비용 있음 |
| 멀티스레드 | - 자원 공유가 쉬움 - 생성/전환 비용이 상대적으로 적음 - 응답성 향상 가능 |
- 프로세스 내부 자원을 공유하기 때문에 동기화가 필요함 - 디버깅 어려움 - 한 곳의 문제가 전체에 영향 |
5. 백엔드 개발에서는 이게 어떻게 보일까?
5-1. 여러 사용자의 요청을 동시에 처리해야 한다.
백엔드 서버는 보통 여러 사용자의 요청을 동시에 처리해야 한다.
많은 백엔드 서버에서는 각 요청을 처리하는 과정에서 스레드가 사용된다.
5-2. 왜 스레드?
요청이 동시에 들어오면, 서버는 겹쳐 처리할 수 있어야 한다.
하나의 요청을 다 끝내고 나서 다음 요청을 처리하는 구조라면 서버 응답성은 매우 떨어진다.
그래서 여러 실행 흐름이 필요하다.
5-3. 그러면 무조건 좋은 건가?
스레드는 같은 프로세스의 자원을 공유한다.
그래서 여러 요청이 같은 데이터에 동시에 접근할 수 있고, 그러면 문제가 생길 수 있다.
특히 읽기 -> 계산 -> 쓰기처럼 여러 단계로 이루어진 작업에서 잘 발생한다.
예를 들어 재고 감소, 포인트 차감 같은 작업에서는 동시성 문제가 발생할 수 있다.
재고가 5개가 남았고 동시에 2명이 결제를 한다면 재고는 3이 되어야 한다.
그런데 처리 순서가 꼬이면 4가 될 수도 있다.
이건 단순한 로직 문제가 아니라 여러 실행 흐름이 같은 데이터에 동시에 접근하면서 생기는 동시성 문제다.
5-4. 그러면 프로세스는?
백엔드에서는 요청 처리 단위로는 스레드를 먼저 체감하는 경우가 많다.
하지만 프로세스는 실행 환경의 경계와 격리 범위를 이해할 때 중요하다.
하나의 애플리케이션 서버, DB, Redis는 각각 별도의 프로세스로 동작할 수 있고,
서버를 여러 대 띄우면 같은 애플리케이션도 여러 프로세스에서 동시에 실행된다.
즉, 같은 데이터를 수정하는 주체는 한 프로세스 안의 여러 스레드일 수도 있고, 여러 프로세스일 수도 있다.
6. 그래서 왜 필요한데?
아무것도 모른다고 생각하고 GPT랑 개발을 진행해 보자.


아 뭐야 동시성이 중요하다고는 들었는데 알아서 해주네~

아 결정은 내가 해야지... 중요한 개념이란 건 알지만 뭐가 뭔지 모르겠다.
알아야 결정할 수 있다는 것을 다시 한번 깨닫는다.
그런데
솔직히 프로세스와 스레드를 안다고 해서
@Version, 낙관적 락, 비관적 락, Redis 중 무엇을 써야 할지가 바로 결정되지는 않는다.
실제 선택은 데이터가 어디에 있고, 동시에 접근하는 범위가 어디까지인지, 정합성이 얼마나 중요한지, 충돌이 자주 나는지 실패 시 재시도가 가능한지 실제 직면한 상황에 따라 달라진다.
다만 프로세스와 스레드를 알면 적어도 어떤 선택지가 아예 맞지 않는지는 걸러낼 수 있다.
예를 들어 여러 서버 인스턴스가 같은 DB 재고를 수정하는 상황이라면, 한 프로세스 내부에서만 유효한 synchronized 같은 방식으로는 해결할 수 없다. (인스턴스 - 실제로 실행 중인 애플리케이션 한 개를 뜻하며, 실무에서는 프로세스와 비슷하게 쓰이기도 한다.)
Redis 분산락은 여러 프로세스나 여러 서버 인스턴스가 같은 자원에 접근할 때 필요한 경우가 많다. 반면 같은 프로세스 내부에서 여러 스레드가 메모리 값을 갱신하는 문제라면, synchronized나 atomic 변수 같은 내부 동기화 방법으로도 충분할 수 있다.
결국 이 개념들은 해결책 자체라기보다, 문제의 범위를 이해하고 틀린 선택을 줄이기 위한 기반 지식에 가깝다.
(@Version, 낙관적 락, 비관적 락, Redis 분산락, synchronized 등의 개념은 차차 알아가기로..)
7. 결론
한 번의 공부로 선명해질 거라 생각하지는 않았다.
이번 공부로
스레드를 통해서 한 서버 안에서도 동시에 처리되기 때문에 충돌이 생길 수 있구나.
프로세스를 통해서 그 충돌은 한 서버 안에서 끝나지 않을 수 있구나.
정도 알고 나아가면 더 선명해질 거라 믿는다.
Reference
- GPT
- 혼자 공부하는 컴퓨터구조 + 운영체제