이 영역을 누르면 첫 페이지로 이동
Coding Groot 블로그의 첫 페이지로 이동

Coding Groot

페이지 맨 위로 올라가기

Coding Groot

코딩 블로그

IPC

  • 2025.03.20 01:51
  • DevOps, Infra/Linux
글 작성자: Coding Groot

IPC(Inter-Process Communication)

IPC란 여러 프로세스가 서로 데이터를 주고 받으면서 협력할 수 있도록 하는 방법이다.

프로세스는 독립적인 실행 객체이기 때문에 서로 통신하기 어렵다는 문제가 있다.

다른 프로세스간 통신을 하려면 커널단에서 제공되는 IPC를 사용해야 한다.

여러 IPC 방법들에 관해 알아보자!

1. Shared Memory

프로세스가 공유 메모리 할당을 요청하면 커널은 해당 프로세스에 메모리 공간을 할당해준다. 그 메모리를 어떤 프로세스건 커널의 관여 없이 접근할 수 있다.

장점

  • 데이터 전송 속도가 빠르다.

단점

  • 데이터를 읽어야 하는 시점을 알기 어렵다
  • 쓰레드와 비슷하게 동시에 같은 메모리에 접근할 수 있기 때문에 동기화 문제를 해결해야 한다.
from multiprocessing import Process, Array

def writer(shared_array):
    # 데이터를 공유 메모리에 쓰기
    data = [1, 2, 3, 4]
    for i in range(len(data)):
        shared_array[i] = data[i]
    print("Writer Process: Data written to shared memory:", list(shared_array))

def reader(shared_array):
    # 공유 메모리에서 데이터 읽기
    data = [shared_array[i] for i in range(len(shared_array))]
    print("Reader Process: Data read from shared memory:", data)

if __name__ == "__main__":
    # 공유 메모리 생성 (정수형 배열, 크기 4)
    shared_array = Array('i', 4)

    writer_process = Process(target=writer, args=(shared_array,))
    writer_process.start()
    writer_process.join()

    reader_process = Process(target=reader, args=(shared_array,))
    reader_process.start()
    reader_process.join()

2. Message Passing

프로세스들이 커널을 통해 메시지를 주고받는 방식이다.

대표적인 방법으로 Pipe, Message Queue, Socket이 있다.

여기에는 두 가지 통신 방법이 있다.

  1. 직접 통신: 프로세스A가 자원을 커널의 메시지 큐로 전달하고 커널이 그 자원을 프로세스B에게 전달하는 방식
  2. 간접 통신: 프로세스A가 자원을 커널의 메시지 큐로 전달하고 프로세스B가 와서 자원을 읽어가게 하는 방식

장점: 높은 커널 의존성을 가지게 되므로 속도가 비교적 느리다.

단점: 운영체제를 통하기 때문에 자원에 대한 동기화 문제는 발생하지 않는다.

2-1. Pipe

단방향 or 양방향 데이터 스트림을 통해 프로세스 간에 데이터를 전달한다.

읽는 쪽과 쓰는 쪽이 정해져 있는 단순한 데이터 흐름에 적합하다.

“단방향 파이프 (Unnamed Pipe)”

echo "Hello from parent!" | cat
  • 부모 프로세스가 자식 프로세스로 데이터를 단방향으로 전달한다

“양방향 파이프 (Named Pipe, FIFO)”

리눅스에서는 mkfifo 명령어를 사용하여 이름 있는 네임드 파이프인 FIFO를 만들 수 있다.

  1. FIFO 파일 생성
  2. mkfifo /tmp/my_fifo
  3. 잠시 서버 역할을 할 shell에서 읽기/쓰기 작업
    • FIFO에서 데이터를 읽고 그 내용을 출력한다
    • &는 백그라운드에서 실행할 때 사용하는 것
  4. cat < /tmp/my_fifo &
  5. 해당 shell에서 FIFO에 데이터를 써보자
  6. echo "Hello from server!" > /tmp/my_fifo
  7. 클라이언트 역할을 할 shell에서 읽기/쓰기 작업
  8. echo "Hello from client!" > /tmp/my_fifo cat < /tmp/my_fifo # 응답을 읽어보자!

데모

영상

2-2 Message Queue

프로세스 간의 메시지 교환을 큐를 통해 비동기적으로 수행할 수 있는 방법이다.

비동기: 메시지를 받는 프로세스가 즉시 응답하지 않아도 된고 메시지를 보낸 프로세스는 딴 작업을 계속할 수 있다

큐 = FIFO: 메시지를 보내는 순서대로 받는다는 것이 보장된다

여러 프로세스가 동일한 큐를 통해 메시지를 주고받을 수 있어서 다중 소비자/생산자 패턴을 쉽게 구현할 수 있다.

리눅스에서 메시지 큐는 msgget, msgsnd, msgrcv 등의 System Call을 사용한다. 파이썬에서 multiprocessing 모듈의 Queue를 사용하여 동일한 기능을 시뮬레이션해보자.

import os
import sysv_ipc
import time

# 메시지 큐 키값 <- 메시지를 식별하기 위해 필요
key = 128

def producer():
    # 메시지 큐 생성
    mq = sysv_ipc.MessageQueue(key, sysv_ipc.IPC_CREAT)

    for i in range(1, 6):
        message = f"구름 출석체크 {i}일차!"
        mq.send(message.encode())  # 메시지 전송
        print(f"Producer sent: {message}")
        time.sleep(1)

def consumer():
    # 메시지 큐에 연결
    mq = sysv_ipc.MessageQueue(key)

    while True:
        message, _ = mq.receive()  # 메시지 수신
        print(f"Consumer received: {message.decode()}")
        if message.decode() == "구름 출석체크 3일차!":
        # 바로 안 처리해도 ㄱㅊ!
            break

    print("딴거 작업!!")
    #time.sleep(3)

    while True:
        message, _ = mq.receive()  # 메시지 수신
        print(f"Consumer received: {message.decode()}")
        if message.decode() == "구름 출석체크 5일차!":
            break

if __name__ == "__main__":
    pid = os.fork()

    if pid == 0:
        consumer()  # 자식 프로세스는 소비자 역할
    else:
        producer()  # 부모 프로세스는 생산자 역할
        os.waitpid(pid, 0)  # 자식 프로세스가 끝날 때까지 대기

데모

영상

2-3 Sockets

네트워크를 통해 프로세스 간 통신을 지원하는 방법이다.

대표적으로 우리가 익숙한 서버-클라이언트 구조에서 사용된다.

당연히, 네트워크 상의 다른 시스템에 있는 프로세스와도 통신할 수 있다.

우리가 배우는 웹서버를 포함하여 SSH, DNS, 등의 서버가 소켓 위에 빌드된 대표적인 서비스이다.

(소켓 통신 코드는 생략!)

면접 질문 예상해보기

IPC에서 공유 메모리와 메시지 전달 방식의 차이점은 무엇이며, 각각의 장단점에 대해 설명해보세요

공유 메모리는 여러 프로세스가 동일한 메모리 영역을 공유하여 데이터를 주고받는 방식입니다. 이 방법은 데이터 전송 속도가 매우 빠르다는 장점이 있지만, 프로세스 간 동기화 문제를 해결하기 위해 세마포어와 같은 Lock을 사용해야 합니다. 동기화가 잘못되면 레이스 컨디션이나 데드락과 같은 문제가 발생할 수 있습니다.

메시지 전달 방식은 커널을 통해 프로세스 간에 메시지를 주고받는 방식으로, 파이프, 메시지 큐, 소켓 등이 있습니다. 이 방법은 프로세스 간의 간섭이 적어서 동기화 문제를 해결할 필요가 적지만, 데이터 전송 속도가 비교적 느릴 수 있습니다. 또한 커널을 경유하기 때문에 시스템 콜 오버헤드가 발생할 수 있습니다.

반응형

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • Terminal과 Shell

    Terminal과 Shell

    2022.04.08
  • Vim에서 Vundle 삭제하기

    Vim에서 Vundle 삭제하기

    2021.03.31
  • [WSL1/WSL2] 홈 디렉터리 위치 :: WSL 홈으로 Windows 파일 옮기기

    [WSL1/WSL2] 홈 디렉터리 위치 :: WSL 홈으로 Windows 파일 옮기기

    2020.05.16
  • [리눅스] apt, apt-get의 사용법 비교

    [리눅스] apt, apt-get의 사용법 비교

    2020.05.01
다른 글 더 둘러보기

정보

Coding Groot 블로그의 첫 페이지로 이동

Coding Groot

  • Coding Groot의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록
  • 소개
  • 블로그 저작권

카테고리

  • 분류 전체보기 (186)
    • Git (23)
      • Git Tutorial (9)
      • Git Note (7)
      • Git Lecture (7)
    • Programming Language (1)
      • C (2)
      • C Sharp (5)
      • Java (4)
      • JavaScript (7)
      • Julia (5)
      • Python (4)
    • Programming (8)
      • Algorithm (2)
      • Compiler (5)
      • Data Structure (0)
      • Web (12)
      • NestJS (2)
    • DevOps, Infra (36)
      • Apple (6)
      • Cloud (15)
      • Database (1)
      • Network (4)
      • Linux (8)
    • Game Programming (11)
      • Unity Tutorial (5)
      • Unity Note (6)
    • Hardware Design (1)
      • Digital Circuit (1)
    • Note (20)
      • Coffee (2)
      • Retrospect (15)
      • Reading List (14)
    • Mathematics (1)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • tutorial
  • javascript
  • aws
  • 한빛미디어
  • 회고
  • Github
  • git
  • 서평
  • 전체 보기…

정보

Coding Groot의 Coding Groot

Coding Groot

Coding Groot

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기

나의 외부 링크

  • GitHub
  • SlideShare
  • 유니티 2020 수업
  • TIL Blog
  • 모도코

방문자

  • 전체 방문자
  • 오늘
  • 어제
Powered by Tistory / Kakao. Copyright © Coding Groot.

티스토리툴바