2025. 2. 8. 13:41ㆍ정보기술/운영체제 (OS)
4️⃣ 프로세스 간 데이터를 주고받는 방법 (메시지 큐, 소켓, 시그널 등)
이전 장에서는 프로세스 간 데이터를 공유하는 방식(공유 메모리, 파일, 파이프) 에 대해 다뤘습니다. 이번에는 프로세스 간 데이터를 주고받는 방법을 알아보겠습니다.
프로세스는 독립적인 실행 단위이므로, 데이터를 주고받기 위해 운영체제가 제공하는 메시지 큐, 소켓, 시그널 같은 통신 방법을 사용해야 합니다.
📌 1️⃣ 메시지 큐 (Message Queue)
메시지 큐는 운영체제가 제공하는 큐(Queue)를 이용해 프로세스 간 데이터를 주고받는 방식입니다.
이 방식은 한 프로세스가 메시지를 큐에 넣고, 다른 프로세스가 큐에서 메시지를 가져가는 방식으로 동작합니다.
🔹 동작 방식
- 프로세스 A가 운영체제에 메시지를 보냄 (큐에 메시지 추가)
- 운영체제가 메시지를 저장하고 관리
- 프로세스 B가 큐에서 메시지를 읽음
📌 비유: 편지함을 이용한 통신
➡️ 회사에서 직원들이 편지함을 이용해 문서를 주고받는 방식과 유사합니다.
➡️ 문서를 보낸 사람이 직접 상대방에게 전달하지 않고 중간 저장소(큐)에 넣으면, 상대방이 나중에 이를 가져갈 수 있습니다.
➡️ 즉, 송신자와 수신자가 동시에 실행될 필요가 없으며, 비동기 방식으로 통신할 수 있음.
✅ 사용 사례
- 운영체제 내부에서 프로세스 간 데이터 전달
- 비동기 이벤트 처리 (예: 프린터 대기열)
- 분산 시스템에서 비동기 메시지 전송
🚀 예제 코드 (C 언어)
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msg_buffer {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("queuefile", 65);
int msgid = msgget(key, 0666 | IPC_CREAT);
struct msg_buffer message;
message.msg_type = 1;
strcpy(message.msg_text, "Hello from Message Queue!");
msgsnd(msgid, &message, sizeof(message.msg_text), 0);
printf("Message Sent: %s\n", message.msg_text);
return 0;
}
📌 2️⃣ 소켓 (Socket)
소켓(Socket) 은 네트워크를 통한 프로세스 간 통신을 가능하게 하는 방식입니다.
소켓을 사용하면 같은 컴퓨터 내 프로세스 간 통신(로컬 소켓)뿐만 아니라, 네트워크를 통한 원격 프로세스 간 통신도 가능합니다.
🔹 동작 방식
- 서버 프로세스가 소켓을 열고 대기(Listening)
- 클라이언트 프로세스가 소켓을 통해 서버에 접속
- 데이터 송수신 후 연결 종료
📌 비유: 인터넷을 이용한 채팅 시스템
➡️ 채팅 프로그램(예: 카카오톡, WhatsApp) 과 비슷합니다.
➡️ 사용자가 메시지를 입력하면 네트워크를 통해 상대방에게 전달됩니다.
➡️ 채팅 서버는 여러 클라이언트의 요청을 받아 처리합니다.
✅ 사용 사례
- 웹 서버와 클라이언트 간 통신 (HTTP, HTTPS)
- 온라인 게임에서 플레이어 간 데이터 전송
- 분산 컴퓨팅 및 원격 프로세스 간 통신
🚀 예제 코드 (Python) - 간단한 채팅 서버
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 12345))
server_socket.listen(1)
print("Waiting for connection...")
conn, addr = server_socket.accept()
print(f"Connected by {addr}")
while True:
data = conn.recv(1024).decode()
if not data:
break
print(f"Client: {data}")
conn.sendall("Message received!".encode())
conn.close()
📌 3️⃣ 시그널 (Signal)
시그널(Signal) 은 운영체제가 프로세스에게 특정 이벤트가 발생했음을 알리는 방법입니다.
일반적으로 프로세스를 종료하거나 인터럽트를 처리하는데 사용됩니다.
🔹 동작 방식
- 특정 이벤트(예: 키보드 입력, 오류 발생)가 발생하면 운영체제가 해당 프로세스에 시그널을 보냄.
- 프로세스는 시그널을 받아 처리할 수 있음.
- 특정 시그널을 받으면 프로세스를 종료하거나, 특별한 동작을 수행할 수 있음.
📌 비유: 긴급 알람 시스템
➡️ 화재 경보 시스템과 유사합니다.
➡️ 건물 내에서 화재가 발생하면 알람(시그널) 이 울려 모든 사람들이 대피할 수 있도록 경고합니다.
➡️ 특정 신호를 받아야만 움직이도록 설계된 시스템과 비슷합니다.
✅ 사용 사례
- 프로세스 종료 요청 (SIGTERM, SIGKILL)
- 사용자 입력 처리 (Ctrl + C → SIGINT)
- 특정 이벤트 발생 알림 (SIGHUP, SIGUSR1)
🚀 예제 코드 (C 언어)
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handle_signal(int signal) {
printf("Received Signal: %d\n", signal);
}
int main() {
signal(SIGINT, handle_signal); // Ctrl+C 시그널 처리
while (1) {
printf("Running... Press Ctrl+C to stop.\n");
sleep(2);
}
return 0;
}
📌 정리
✔️ 메시지 큐(Message Queue)
✅ 운영체제가 제공하는 큐를 이용한 통신
✅ 송신자와 수신자가 동시에 실행될 필요 없음 (비동기)
✅ 예: 프린터 대기열, IPC 메시지 전송
✔️ 소켓(Socket)
✅ 네트워크를 통한 프로세스 간 통신
✅ 같은 시스템 내(Local Socket) 및 원격 시스템 간(Network Socket) 사용 가능
✅ 예: 채팅 프로그램, 웹 서버-클라이언트 모델
✔️ 시그널(Signal)
✅ 운영체제가 특정 이벤트를 프로세스에 전달하는 방식
✅ 프로세스 종료, 사용자 입력 처리 등에 사용
✅ 예: Ctrl+C 인터럽트, 긴급 알림 시스템