본문 바로가기
Computer Science/UNIX & Linux

[UNIX/Linux] ep10-1+) 메시지 큐 함수 실습

by 클레어몬트 2024. 11. 7.

hw. 자식이 표준 입력한 내용을 mtype=1로 부모에게 전달한다. 더 이상의 내용이 없을 때 자식은 “bye”와 mtype=2를 전달한다. 부모는 mtype=1이면 받은 내용을 표준 출력하고, mtype=2이면 종료하는 프로그램을 작성하라.

 

(메시지 큐가 가장 적합)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>

#define MSGSIZE 128  // 메시지의 최대 크기 정의

// 메시지 버퍼 구조체 정의
struct msgbuf {
    long mtype;           // 메시지 유형
    char mtext[MSGSIZE];  // 메시지 내용
};

// 부모 프로세스 함수: 자식 프로세스가 보낸 메시지를 수신
void parentProcess(int msgid) {
    struct msgbuf msg;
    while (1) {
        // msg 큐에서 메시지를 수신 (0을 지정하여 모든 메시지 유형을 받음)
        msgrcv(msgid, &msg, sizeof(msg.mtext), 0, 0);
        
        if (msg.mtype == 1) {  // 메시지 유형이 1인 경우
            printf("Received message: %s\n", msg.mtext);  // 메시지 출력
        } else if (msg.mtype == 2) {  // 메시지 유형이 2인 경우
            printf("Exit message received. Exiting...\n");  // 종료 메시지 출력
            break;  // 반복문 종료
        }
    }
}

// 자식 프로세스 함수: 사용자 입력을 받아 부모 프로세스에 메시지 전송
void childProcess(int msgid) {
    struct msgbuf msg;
    char input[MSGSIZE];

    while (1) {
        printf("Enter message: ");  // 메시지 입력 요청
        fgets(input, MSGSIZE, stdin);  // 사용자로부터 입력 받기
        input[strcspn(input, "\n")] = '\0';  // 개행 문자 제거

        msg.mtype = 1;  // 메시지 유형을 1로 설정
        strcpy(msg.mtext, input);  // 입력된 내용을 메시지 버퍼에 복사
        msgsnd(msgid, &msg, sizeof(msg.mtext), 0);  // 메시지를 큐에 전송

        if (strcmp(input, "bye") == 0) {  // 입력이 "bye"인 경우
            msg.mtype = 2;  // 메시지 유형을 2로 설정 (종료 메시지)
            msgsnd(msgid, &msg, sizeof(msg.mtext), 0);  // 종료 메시지를 큐에 전송
            break;  // 반복문 종료
        }
    }
}

int main() {
    // 메시지 큐 생성 (IPC_PRIVATE: 프로세스 간 개인 큐 생성, 0666: 읽기/쓰기 권한)
    int msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
    if (msgid == -1) {  // 메시지 큐 생성 실패 시
        perror("msgget failed");
        exit(1);
    }

    // 자식 프로세스 생성
    pid_t pid = fork();
    if (pid == -1) {  // fork 실패 시
        perror("fork failed");
        exit(1);
    } else if (pid == 0) {  // 자식 프로세스의 경우
        childProcess(msgid);  // 자식 프로세스 함수 실행
    } else {  // 부모 프로세스의 경우
        parentProcess(msgid);  // 부모 프로세스 함수 실행
        wait(NULL);  // 자식 프로세스가 종료될 때까지 대기
        msgctl(msgid, IPC_RMID, NULL);  // 메시지 큐 삭제
    }

    return 0;
}

 

 

 

 

 

 

 

참고 및 출처: 시스템 프로그래밍 리눅스&유닉스(이종원)