백과 블로그
홈블로그소개

백과의 개인 블로그 입니다. Contact : ksu9801@gmail.com

운영체제

프로세스와 스레드

백과
2025년 7월 7일
5분 읽기
목차
📚 프로세스와 스레드
✅도입
📌 프로세스, 스레드 란?
✅프로세스
📌 프로세스 정의
📌 프로세스의 구성
📌 PCB와 문맥 교환( Context Switching )
📌 프로세스의 상태
📌 블로킹과 논블로킹
✅ 멀티 프로세스 & 멀티 스레드
📌 도입
📌 멀티 프로세스
📌 멀티 프로세스 특징
📌 멀티스레드
📌 멀티 스레드 특징
📌 멀티프로세스 vs 멀티스레드
📌 스레드 조인
✅ 프로세스 간 통신
📌 도입
📌 공유 메모리
📌 메시지 전달
📌 메시지 전달 방식 상세
📄 출처

목차

📚 프로세스와 스레드
✅도입
📌 프로세스, 스레드 란?
✅프로세스
📌 프로세스 정의
📌 프로세스의 구성
📌 PCB와 문맥 교환( Context Switching )
📌 프로세스의 상태
📌 블로킹과 논블로킹
✅ 멀티 프로세스 & 멀티 스레드
📌 도입
📌 멀티 프로세스
📌 멀티 프로세스 특징
📌 멀티스레드
📌 멀티 스레드 특징
📌 멀티프로세스 vs 멀티스레드
📌 스레드 조인
✅ 프로세스 간 통신
📌 도입
📌 공유 메모리
📌 메시지 전달
📌 메시지 전달 방식 상세
📄 출처

image

📚 프로세스와 스레드

✅도입

📌 프로세스, 스레드 란?

프로세스는, 현재 실행 중인 프로그램 이라고 생각하면 된다. 스레드는, 프로세스 내에서 실제로 작업을 수행하는 실행 흐름(작업 단위) 프로세스: “회사(건물)” 스레드: “회사 안에서 일하는 직원(일꾼)” 회사는 여러 명의 직원(스레드)이 동시에 일할 수 있고, 회사(프로세스)마다 자원(방, 컴퓨터, 서류 등)은 독립적으로 관리

✅프로세스

📌 프로세스 정의


  • 우리가 실행하는 프로그램은, 실행되기 위해서, 메모리에 적재가 되어 실행되게 된다. (프로세스)
  • 이 프로세스는, 포그라운드 프로세스 와 백그라운드 프로세스로 나눠지게 된다.
  • 보통 사용하게 되는 익스플로어나, 게임 등등은 모두 포그라운드 프로세스 이다.
  • 사용자가 보지 못하는 곳에서 실행되는 것을 백그라운드 프로세스 라고 지칭한다.

백그라운드 프로세스 중, 사용자와 상호작용 없이 주어진 작업만 수행하는 프로세스를 데몬 혹은 서비스(윈도우 환경) 이라고 한다.

📌 프로세스의 구성

  • 프로세스는 실행되기 위해서, 메모리에 반드시 적재가 되어야 하는데 다음과 같은 형태로 적재되어있다. image
  • 사용자 영역에는 코드 영역, 힙 영역, 데이터 영역, 코드 영역 4가지 영역으로 관리되고, 커널 영역에는 프로세스 제어 블록(PCB) 라는 정보가 저장되게 된다.

코드 영역

  • 코드 영역은 실행 가능한 명령어가 저장되는 공간으로 텍스트 영역 이라고도 부른다.
  • CPU 가 읽고 실행할 명령어가 담겨 있기 때문에, 읽기 전용 공간

데이터 영역

  • 데이터 영역은 프로그램이 실행되는 동안 유지할 데이터가 저장되는 공간.
  • 주로, 정적 변수나 전역 변수 등이 저장되는 공간.
  • 코드 영역과 데이터 영역은 실행 도중 크기가 변하지 않기 때문에 정적 할당 영역 이라고 부른다.

힙 영역

  • 힙 영역은, 프로그램 사용자(개발자)가 직접 할당 가능한 저장 공간.
  • 사용하지 않을 때는, 할당 취소(반납)을 진행해야 하는데, 계속 점유해서 메모리 공간을 낭비하는 경우, 문제를 메모리 누수 문제라고 한다.
  • EX) C에서, malloc() 으로 할당 후, free() 를 통해 반납 진행
  • JAVA 등 에서는, 가비지 컬렉션(GC) 가 자동으로 메모리를 해제하는 기능을 제공

스택 영역

  • 스택 영역은 일시적으로 사용할 값들이 저장되는 공간
  • 함수의 실행이 끝나면 사라지는 매개변수, 지역변수, 함수 복귀 주소 등이, 스택 영역에 저장되는 데이터들 이다.
  • 힙 영역과 스택 영역은 실행 중, 크기가 변동 하는 데이터로 동적 할당 영역 이라고 부른다.

커널 영역의 PCB

  • 프로그램이 실행되려면 결국 메모리에 있는 코드 영역등을 CPU 가 읽고 실행해야된다.
  • 이때, 다양한 작업들이 대기 중 인데, PCB는 이 작업들의 정보를 나타낸다.
  • PCB 내부에는 프로세스를 식별하기 위한 프로세스 ID(PID), 프로세스가 실행 과정 중 사용한 레지스터 값, 프로세스가 어떤 상태인지 나타내는 프로세스 상태, 어떤 순서로 CPU를 할당 받을지 나타내는 CPU 스케줄링(우선순위) 정보 등이 저장된다.
  • 이러한 데이터는 PCB에서는 프로세스 테이블의 형태로 관리되는 경우가 많다.
  • 새롭게 실행되는 프로세스는 PCB를 프로세스 테이블에 추가하고, 종료되는 프로세스는 프로세스 테이블에서 삭제된다.
  • 즉, 프로세스 테이블은 현재 실행 중인 PCB의 모음을 의미합니다. image
  • 프로세스가 비정상적으로 종료되어, 사용한 자원이 회수 되었음에도, 프로세스 테이블에 종료된 프로세스의 PCB가 남아있는 경우가 있는데, 이를 좀비 프로세스라고 한다.

📌 PCB와 문맥 교환( Context Switching )


  • 운영체제는, PCB를 통해 어떤 작업을 CPU 에게 할당할지 결정 하고, 작업을 지시한다.
  • 이때 기본적으로 한 CPU는 하나의 작업 만을 처리할 수 있다.
  • 즉, 프로세스 A, B 두 개가 있고 1개의 CPU 코어가 있다면, 먼저 하나의 프로세스를 처리하고, 남은 나머지 하나의 프로세스를 처리한다.
  • 만약, 각 프로세스가 10분 정도 걸린다고 한다면, A -> B 의 순서에서 B작업은 10분뒤 부터 실행될까? ❌
  • 실제로는 A -> B -> A -> B .... -> A -> B 와 같이 엄청 빠른속도로 작업을 바꿔가며 진행하게 된다.

정확 하게 프로세스가 실행의 단위가 아니고 추후에 나올 스레드가 실행의 단위가 된다. 아직 설명하지 않았기 때문에 간단히, 작업이 번갈아 가며 동작한다, 라고 기억하자.

image

  • 번갈아 가며 실행되기 때문에, 각 작업을 얼만큼 실행할지, 어디서 부터 실행할지를 알아야 한다.
  • 얼만큼 실행할지는, 사실 한 작업이 얼만큼 CPU를 사용할 수 있는 지? 에 대한 내용이고, 이는 타이머 인터럽트에 의해 제한됩니다.
  • 즉, 한 작업은 할당된 최대 시간만큼만 CPU를 차지해서 처리하고, 타이머 인터럽트가 발생하면 자신의 차례를 반납하고 CPU를 놓아줍니다.

image

  • 그렇다면 작업 A를 두번째 실행할때는 다시 처음부터 시작해야 할까?
  • 매우 비 효율 적이며, 절대 작업은 끝나지 않을 것이다.
  • 따라서, 이전까지 작업한 중간 정보를 백업 하고 불러와야 한다.
  • 이때 백업할 정보를 문맥(context) 라고 한다.
  • 문맥에는, 프로그램 카운터, 레지스터 값, 메모리 정보, 실행을 위해 열었던 파일, 사용한 입출력 장치 등 여러가지 내용을 포함한다.
  • 문맥은, 일반적으로 각 PCB 에 저장되어 있다.

image

  • 이와 같이 CPU 가 여러 작업을 빠르게 돌아가면서 처리하게 되는데, 이를 시분할 시스템 이라고 부른다.

📌 프로세스의 상태


  • 하나의 프로세스는 여러 상태를 거치며 실행된다.
  • 운영체제는 PCB를 통해 프로세스의 상태를 인식하고 관리하는데, 이때 사용되는 프로세스 상태는 대표적으로 다음과 같다.
  • 생성, 준비, 실행, 대기, 종료 등이 있다.
  • 생성(new) : 프로세스를 생성 중인 상태. 메모리에 적재되어 PCB를 할당 받은 상태
  • 준비(ready) : CPU 할당을 받아 실행될 수 있지만, 대기하고 있는 상태.
  • 실행(running) : CPU 할당을 받아 실행되는 상태
  • 대기(blocked) : 프로세스가 실행 도중, 바로 실행이 불가능한 상태일 경우. 외부 입출력 장치를 사용하여 입출력 장치의 작업이 끝날때 까지 기다려야 되는 경우 등
  • 종료(terminated) : 프로세스가 종료된 상태
  • 이 밖에도, 상태에서 상태로 이동할때 사용되는 용어도 존재한다.
  • 디스패치(Dispatch) : 준비 상태에서, CPU 할당을 받아 실행 상태로 변경되는 것
  • 시간 종료(Timeout) : 실행중인 프로세스가 할당된 시간을 모두 사용하여 타이머 인터럽트되어 준비 상태로 변경되는 것
  • 블록(Block) : 실행중인 프로세스가 입출력 완료 대기 등을 위해 대기 상태로 들어가는 것
  • Wakeup : 대기 중인 프로세스가 입출력 등이 완료되어 준비 상태로 들어가 CPU 할당 대기를 받으러 가는 것

image

📌 블로킹과 논블로킹


  • 실행상태의 프로세스는, 입출력 작업 등을 처리해야 되는 경우 (외부 작업), 대기 상태로 들어가, 입출력 작업이 완료되기를 기다린다.
  • 이후, 완료되면 준비 상태로 돌입하게 되는데, 이를 블로킹 입출력(Blocking I/O) 라고 한다.
  • 하지만, 모든 작업이 반드시 대기 상태에 접어들 필요가 없다.
  • 예시로, A 프로세스는, DB에 1이라는 숫자를 저장하는 작업을 수행한다고 하면, 기다릴 필요 없이 저장 작업만 진행되면 된다.

저장 결과를 확인해야 하는 반례의 케이스가 있을 수 있지만, 결과 확인에 따라 분기가 되지 않는 단순한 작업이었다고 생각하자.

  • 즉, 입출력 장치에게 작업을 맡긴 후, 곧바로 다음 작업을 실행할 수도 있다.
  • 이를 `논블로킹 입출력(non-blokcing I/O) 라고 한다.

✅ 멀티 프로세스 & 멀티 스레드

📌 도입


  • 만약, 한 프로세스를 구성하는 코드를 동시에 실행하려면 어떻게 해야 할까?
  • 즉, Chrome을 여러개 띄워가며 웹서핑을 즐기려면 어떻게 해야 할까?
  • 크게 두가지 방법이 존재한다. 멀티 프로세스, 멀티 스레드

📌 멀티 프로세스


  • 하나의 작업을 여러개의 프로세스로 분리해서 동시에 실행하는 구조
  • Chrome등 브라우저의 탭이 가장 대표적인 예시이다.
  • 윈도우 기준, 작업관리자에서 Chrome 브라우저를 여러개 실행한 뒤, 확인해보면 다음과 같이 각 탭은 각 프로세스로 구성되어 있다. image
  • 이렇게 동시에 여러 프로세스가 실행되는 것을 멀티 프로세스 라고 한다.

📌 멀티 프로세스 특징


  • 멀티 프로세스는 같은 작업을 진행하지만, 모두 독립적인 작업들이다.
  • 즉, PCB가 각각의 프로세스마다 다르게 가지고 있고, 그에 따라 PID(프로세스 ID) 또한 다 다르다.
  • 각 별도의 메모리 공간을 할당 받고, 같은 프로세스라고 해서, 서로 통신하거나 영향을 끼치지 않는다. (독립성)

📌 멀티스레드


  • 또다른 동시에 같은 작업을 실행하는 방법은 멀티스레드 이다.
  • 하나의 프로세스 내에서 여러 개의 스레드가 동시에(병렬/병행) 실행되는 구조를 말한다.
  • 멀티 프로세스와 달리, 여러 스레드가 하나의 프로세스 메모리 공간을 공유하면서 각자 실행 흐름(작업)만 독립적으로 관리한다.

📌 멀티 스레드 특징


  • 멀티 스레드는, 스레드간 공유할 수 있는 자원이 있다.
  • 물론, 각 스레드의 고유한 스레드ID, 프로그램 카운터, 레지스터 값 등은 별도로 구분되어 공유되지 않는다.
  • 이는, 자신에게 할당된 스택 영역에 저장된다.
  • 하지만, 전역 변수, 정적 변수 등, 공유할 수 있는 프로세스 자원은 공유하여 사용된다.

image

📌 멀티프로세스 vs 멀티스레드


  • 둘은 비슷하면서도 달라, 올바른 차이점을 인지하는게 중요하다.
구분멀티프로세스멀티스레드
실행 단위여러 개의 프로세스하나의 프로세스 내 여러 스레드
PID/PCB각각 고유(PID, PCB 따로)동일한 PID, 각 스레드는 TCB(스레드제어블록)
메모리 공간완전히 분리된 메모리 공간(코드/데이터/힙/스택)코드/데이터/힙 공유, 스택만 분리
자원 공유공유 불가(IPC 필요)전역/정적 변수, 힙 등 공유 가능
안정성한 프로세스 종료 시 다른 프로세스 영향 X한 스레드 문제 시 전체 프로세스 영향 가능
데이터 교환느림(IPC: 소켓, 파이프 등 별도 통신 필요)빠름(메모리 직접 접근)
장점안정성, 격리성 높음자원 효율적, 협업/데이터 공유 쉬움
단점메모리 많이 사용, 통신 복잡/느림동기화/경쟁 조건, 오류 전파 가능성
예시크롬 탭, 서버 프로세스워드 자동저장+입력, 서버에서 요청 다중처리
  • 즉, 안정성/격리성이 중요한 서비스의 경우, 멀티프로세스로 구성하고, 자원 활용/데이터 공유를 통해 빠른 데이터 교환이 중요한 서비스라면 멀티스레드로 구성하는 등 다양한 경우가 될 수 있을 것 이다.

둘의 가장 큰 핵심 차이는, 자원의 공유 여부!!

📌 스레드 조인


  • 스레드에서, 다른 스레드가 종료된 후 순차적으로 진행되어야 할 때 어떤식으로 진행해야 할까?
  • join 이라는 명령어가 표준적으로 사용된다.
  • join 은, 해당 스레드가 종료될 때 까지 대기해야 함을 의미한다.
  • 즉, Main 쓰레드에서 Sub 쓰레드의 실행이 완료 된 후, Main 쓰레드가 완료되어야 한다면, 다음과 같이 작성하여 동기 시킨다. (자바 예시)
  • 대부분의 프로그래밍 언어는 join을 제공하고 있으니, 자신이 사용하는 언어의 공식 문서를 확인하여 확인해보자.
public class JoinExample {
    public static void main(String[] args) throws InterruptedException {
        Thread subThread = new Thread(() -> {
            System.out.println("Sub thread 시작");
            try {
                Thread.sleep(2000); // 2초간 대기 (작업하는 척)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sub thread 종료");
        });
 
        subThread.start(); // Sub 스레드 실행
 
        System.out.println("Main thread: subThread가 끝날 때까지 대기");
        subThread.join(); // Main은 subThread가 끝날 때까지 대기
 
        System.out.println("Main thread 종료(모든 작업 완료)");
    }
}
 
Main thread: subThread가 끝날 때까지 대기
Sub thread 시작
Sub thread 종료
Main thread 종료(모든 작업 완료)

✅ 프로세스 간 통신

📌 도입


  • 앞서 프로세스는 기본적으로 자원을 공유 하지 않고 독립적 이라고 하였다.
  • 하지만, 프로세스 간에도 자원을 공유하고 데이터를 주고받을 수 있는 방법이 있다.
  • 이를 프로세스 간 통신(IPC) 라고 한다.
  • 크게 2가지 유형이 있다 (공유 메모리, 메시지 전달)

📌 공유 메모리


  • 공유 메모리는 말 그대로, 데이터를 주고 받는 프로세스가 공통적으로 사용할 메모리 영역을 두는 방식이다.
  • 서로 공유할 수 있는 메모리 영역을 확보하는 시스템 콜을 기반으로 공유할 수 도 있고, 변수나 파일을 활용하여 공유할 수도 있다.

image

  • 가장 중요한 특징은, 각 프로세스가 마치 자신의 메모리 영역을 읽고 쓰는 것 처럼 통신한다는 것이다.
  • 네트워크를 통해 공유 폴더를 생성해 자신의 폴더처럼 활용하지만 실제 연결된 모든 네트워크에서 공유되어 사용되는 경우를 생각해보자.
  • 이 방법은, 프로세스간 데이터를 주고 받을 때 커널 영역을 거치지 않는 경우가 많다.
  • 이러한 방법은, 빠르지만, 레이스 컨디션, 동기화 문제 등이 발생할 수 있다.

📌 메시지 전달


  • 메시지 전달 방식은, 프로세스 간에 주고 받을 데이터가 커널을 거쳐 송수신 되는 통신 방식 입니다.
  • 공유 메모리 IPC 와 달리, 메시지 기반 IPC 는 메시지를 보내는 수단과 받는 수단이 명확하게 구분되어 있다.
  • 메시지를 보내는 send() 시스템콜과, 받는 recv() 시스템 콜을 통해서 송수신 하게 된다.
  • 이는, 시스템 콜을 사용하기 때문에 커널을 사용하게 되고, 공유 메모리보다 상대적으로 느린 속도가 된다.
  • 하지만, 커널의 도움을 받는 만큼 레이스 컨디션, 동기화 문제등 을 고려해야 할 상황이 적다.

📌 메시지 전달 방식 상세


  • 메시지 전달 방식에서는, 파이트 시그널, 소켓, 원격 프로시저 호출(RPC) 등이 사용된다.
  • 파이프
    • 파이프는 단 방향 프로세스 통신을 말한다.
    • 프로세스 A가 데이터를 쓰면, 파이프 반대쪽으로 그 데이터를 프로세스 B가 읽는 구조이다.
    • 양방향 통신을 수행해야 하는 경우에는, 파이프 2개를 이용하는 경우가 많다.
  • 시그널
    • 시그널은 프로세스에게 특정 이벤트가 발생했음을 알리는 비동기적인 신호이다.
    • 프로세스는, 시그널이 발생하면, 진행하던 일을 잠시 중단하고 시그널 처리를 위한 시그널 핸들러를 실행한 뒤 하던 일을 진행 한다.
    • 시그널이 발생했을 대의 동작을 서로 정의하여 이를 활용하여 통신하는 방식이 시그널 방법이다.

시그널은, IPC를 위해 존재하는 개념이 아니고, 시그널을 사용하여 IPC 를 수행할 수 있다.

  • 메시지 큐(message queue)
    • 커널이 관리하는 큐에 메시지를 보내고, 다른 프로세스가 큐에서 메시지를 읽는 구조 (예: POSIX MQ, SysV MQ)
  • 소켓(socket)
    • 네트워크 기반, 동일/다른 머신 간 통신 가능 (TCP/UDP 기반)
    • 현대 IPC의 핵심 (마이크로서비스, 분산시스템 등)
  • 원격 프로시저 호출(RPC)
    • 프로세스가 “네트워크를 통해” 다른 프로세스의 함수를 마치 내 함수처럼 호출
    • 현대 분산 시스템에서 매우 중요 (gRPC, Thrift 등)

📄 출처

  • https://yoongrammer.tistory.com/52
  • https://yanghs6.github.io/posts/1003_process_state/