2025. 8. 11. 18:31ㆍData Analysis/Computer Science
우리가 일상에서 사용하는 모든 소프트웨어는 이러한 원리를 기반으로 동작한다.

컴파일 과정
먼저, 개발자가 작성한 소스 코드(예: C언어로 작성된 세민.c)는 컴파일러라는 번역기를 통해
컴퓨터가 이해할 수 있는 기계어 파일(Chrome.o)로 변환된다.
이 과정에서 전처리, 컴파일, 어셈블, 링킹 단계를 거치며
최종적으로 실행 가능한 프로그램 파일(.exe 또는 .out)이 만들어진다.
프로그램과 프로세스
이렇게 만들어진 프로그램 파일은 그 자체로는 메모리 위에 올라가 있지 않은,
그저 하드디스크에 저장된 ‘정적인 상태’의 파일이다.
우리가 이 파일을 더블 클릭하면, 운영체제는 이 파일을 메모리에 올려놓고 실행을 준비한다.
이처럼 메모리에 올라가서 실행 중인 상태를 프로세스라고 부른다.
운영체제로부터 파일(자원)을 할당받은 작업의 단위를 의미한다.
이는 마치 레시피(프로그램)를 보고 요리(프로세스)를 만드는 것과 같다.
프로세스와 스레드

프로세스는 하나의 작업 단위이지만, 실제 작업의 흐름은 하나 이상일 수 있다.
이 작업의 흐름 하나하나를 스레드라고 한다.
예를 들어, 웹 브라우저(chrome.exe)라는 하나의 프로세스가 있다면,
탭을 여러 개 열거나 동영상을 재생하는 각각의 작업이 스레드로 실행된다.
프로세스는 여러 스레드를 포함하는 컨테이너 역할을 하며,
스레드는 프로세스 내에서 CPU 스케줄링의 최소 단위가 된다.
즉, 하드디스크에 있는 프로그램을 실행하면,
실행을 위해서 메모리 할당이 이루어지고,
할당된 메모리 공간으로 Binary Code가 올라가게 되는데,
이 순간부터 프로세스라 불릴 수 있게 되는 것이다.
소스 코드를 작성하고
→ 컴파일 과정을 거쳐 프로그램을 만들고
→ 사용자가 이 프로그램을 실행하면 프로세스가 되며
→ 이 프로세스 내에서 여러 개의 스레드가 실제 작업을 수행하는 구조이다.
프로세스 LifeCycle과 메모리 구조의 연결
프로세스의 상태(state) 변화는 메모리 구조와 뗄레야 뗄 수 없는 관계를 가진다.
하나의 프로그램이 실행되어 프로세스가 되는 순간부터,
그 프로세스는 OS로부터 메모리의 특정 영역들을 할당받고,
이 메모리 위에서 상태를 바꾸며 작업을 수행한다.

Create와 메모리 할당:
fork()나 exec() 같은 함수로 프로세스가 Create(생성) 상태가 되면,
OS는 가장 먼저 이 프로세스에게 필요한 메모리 공간을 할당한다.
이 공간은 Code, Data, Heap, Stack이라는 네 가지 영역으로 나뉜다.

Ready와 Running:
메모리를 할당받은 프로세스는 Ready(준비) 상태에서 CPU의 차례를 기다린다.
CPU 스케줄러가 이 프로세스를 선택하면,
Running(실행) 상태로 전환되어 Code 영역에 있는 기계어를 실제로 실행하게 된다.
이 과정에서 Stack 영역을 이용해 함수를 호출하고 지역 변수를 저장하며,
Heap 영역을 이용해 동적으로 메모리를 할당받아 데이터를 처리한다.
Blocked와 I/O
프로세스가 I/O 장치(예: HDD)에 접근할 때, 장치의 느린 속도 때문에 CPU는 기다려야 한다.
이때 프로세스는 Blocked 상태로 전환되어 CPU의 소유권을 반납하고,
다른 프로세스가 대신 실행될 수 있도록 한다.
이 시점에서 프로세스는 CPU를 사용하지 않지만, 할당받은 메모리 공간은 그대로 유지한다.
프린트 인쇄를 누르고 기다리는 상황이 대표적인 예시다.
Suspend 상태와 메모리 관리
시스템 메모리가 부족해지면, OS는 Blocked 상태에 있는
프로세스의 메모리 공간을 임시로 디스크에 옮겨 버릴 수 있다.
이 상태가 Blocked Suspend이며,
이는 프로세스의 메모리 구조를 디스크에 통째로 저장하는 일종의 Swap Out 과정이다.
Terminated와 메모리 회수
프로세스가 작업을 마치고 Terminated(종료) 상태가 되면,
OS는 해당 프로세스에 할당했던 모든 메모리 공간(Code, Data, Heap, Stack)을
회수하여 다른 프로세스들이 사용할 수 있또록 한다.
요약하자면, 프로세스의 상태 변화는 OS가 메모리와 CPU를 효율적으로 관리하기 위한 전략이며,
이 모든 과정은 프로세스에 할당된 메모리 구조 위에서 일어난다.
How I Applied It
프로그램 실행 환경 이해
오늘 배운 내용은 실제 분석 환경과 성능 최적화에 직결될 수 있다.
Python, R과 같은 인터프리터 언어에서 컴파일러의 역할을 인터프리터가 대신한다.
파이썬 코드는 실행 시점에 인터프리터에 의해 기계어로 번역되므로,
컴파일 언어(C/C++)보다 속도가 느릴 수 있다는 점을 인지해야 한다.
이러한 특성 때문에 속도 최적화가 중요한 부분에서는
C/C++로 작성된 라이브러리(Numpy, Pandas)를 사용하게 된다.
병렬 처리와 성능 최적화
데이터 분석에서는 대규모 데이터를 다룰 때,
멀티 프로세싱이나 멀티 스레딩을 활용하여 성능을 높이는 경우가 많다.
멀티 프로세싱:
여러 개의 프로세스를 띄워서 작업을 분산 처리하는 방식
파이썬의 multiprocessing 라이브러리가 대표적인 예시이다.
각 프로세스는 독립된 메모리 공간을 갖기 때문에 메모리 공유에 대한 걱정이 적지만,
프로세스 간 통신 비용이 크다는 단점이 있다.
멀티 스레딩:
한 프로세스 내에서 여러 스레드가 동시에 작업하는 방식이다.
파이썬에서는 GIL 때문에 진정한 의미의 멀티 스레딩 병렬 처리는 어렵지만,
I/O 작업 등에서는 효율성을 높일 수 있는데,
데이터 분석이 주로 CPU 작업이 많으므로 멀티 프로세싱이 더 유용하게 사용될 수 있는 것이다.
SQL 쿼리 실행의 내부 동작
SQL은 DB 서버에 요청을 보내는 선언형 언어이다.
우리가 작성한 SQL 쿼리도 결국 서버 내에서 하나의 프로세스로 실행되거나,
더 세부적으로는 스레드로 분할되어 처리된다.
SELECT * FROM table
위와 같은 쿼리를 실행하면,
DB 엔진은 이 쿼리를 하나의 프로세스(또는 세션)으로 인식하고 실행 계획을 수립한다.
이 실행 계획을 실제로 수행하는 과정은 여러 개의 스레드로 나뉘어 병렬 처리될 수 있다.
예를 들어, 대용량 테이블의 Index Scan이나 ORDER BY 작업은
여러 스레드가 동시에 수행하여 처리 속도를 높인다.
DB의 병렬 처리
대규모 데이터를 ETL하거나 복잡한 쿼리를 실행할 때,
이러한 병렬 처리 옵션을 활용하여 쿼리 실행 시간을 단축할 수 있다.
이는 곧 데이터베이스 프로세스 내 스레드를 효율적으로 활용하는 것과 같은 맥락이다.
컴파일과 최적화
SQL 쿼리도 일종의 컴파일 과정을 거친다.
DB는 쿼리를 받으면, Pasing과 Binding을 통해 쿼리의 문법적/의미적 오류를 확인하고,
쿼리 Optimization을 거쳐 쿼리의 문법적/의미적 오류를 확인한다.
'Data Analysis > Computer Science' 카테고리의 다른 글
| 메모리 관리 (3) | 2025.08.05 |
|---|---|
| CPU와 기억장치, 메모리 (3) | 2025.08.04 |
| 운영체제와 컴퓨터 (4) | 2025.08.01 |
| 자료구조는 왜 중요할까? (0) | 2025.03.14 |
| 추상 자료형 (Abstract Data Type) (0) | 2024.07.04 |