[C 언어] IPC - 큐, 공유메모리

태태·2024년 7월 29일

IPC

  • 프로세스 간 통신 → 프로세스들끼리 서로 데이터를 주고 받는 행위를 의미
    • 이때, 프로세스는 독립된 공간이므로 다른 프로세스에 접근하는 것을 허용하지 않음
  • 예시
    • 프로세스 A와 프로세스 B가 데이터를 주고 받으려고 한다면, A는 데이터를 공유된 메모리 영역에 저장하고 B가 꺼내 사용하는 방식
  • IPC 종류
    • 메시지 전달
      • Pipe, Signla, Message Queueing, Socket 등
    • 공유 메모리
      • Semaphores 등
  • 커널 영역에서 IPC 라는 내부 프로세스간 통신을 제공
    • 프로세스는 완전히 독립된 실행 객체 → 다른 프로세스에 영향을 받지 않는다는 장점이 있음
      • 단점으로는, 별도의 설비 없이는 통신이 어려움


메시지 큐

  • FIFO (선입선출) 자료구조를 가지는 통신 설비로 커널에서 관리
  • 사용할 데이터에 번호를 붙여 다수의 프로세스가 동시에 데이터를 쉽게 다룰 수 있음
  • 사용 시기
    • 다른 프로세스와 단방향 통신 시
  • 통신 단위 : 구조체
  • 공유 매개체 : 메모리
  • 장점
    • 비동기 방식 → 방대한 처리량이 있다면 큐에 넣은 후 나중에 처리 가능
    • 다수의 프로세스들이 큐에 메시지를 보낼 수 있고 다수의 프로세스들이 큐로부터 메시지를 꺼낼 수 있음
  • 단점
    • 큐에 데이터 넣고 나오는 과정에서 오버헤드가 발생할 수 있음
    • 데이터가 많을 수록 추가적인 메모리 자원이 필요


메세지 큐 실습 코드

sender.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFSIZE 1024


typedef struct
{
        long msg_type;
        int value;
        char buf[BUFSIZE];
} msgbuf;


int main()
{
        int cnt = 0;
        key_t key = 9999;
        int msgq_id = 0;

        msgbuf msg;
        msg.msg_type = 1;

        msgq_id = msgget(key, IPC_CREAT | 0666);

        if(msgq_id == -1)
        {
                printf("msgget error\n");
                exit(0);
        }

        while(1)
        {
                msg.value = ++cnt;

                if(cnt >= 10)
                {
                        printf("message send finish");
                        break;
                }

                if(msgsnd(msgq_id, &msg, sizeof(msg), IPC_NOWAIT) == -1)
                {
                        printf("msgsnd error\n");
                        exit(0);
                }

                printf("value : %d\n", msg.value);
                sleep(1);
        }

        exit(0);
}

receiver.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFSIZE 1024

typedef struct
{
		//long 부분은 고정!
        long msg_type;
        int value;
        char buf[BUFSIZE];
} msgbuf;

int main()
{
        key_t key = 9999;
        int msgq_id = 0;
        msgbuf msg;
        msg.msg_type = 1;

        msgq_id = msgget(key, IPC_CREAT | 0666);

        if(msgq_id == -1)
        {
                printf("msgget error\n");
                exit(0);
        }

        while(1)
        {
                if(msgrcv(msgq_id, &msg, sizeof(msg), 1, 0) == -1)
                {
                        printf("Message receive finish\n");
                        exit(0);
                }

                printf("value : %d\n", msg.value);
        }

        printf("finsish!!\n");
        exit(0);
}
//Create Message
int masgget (key_t key, int msgflg);

//Send Message
int msgsnd(int msqid, struct msgbuf * msgp, size_t msgsize, int msgflg);

//Receive Message
msgrcv(int msgid, struct msgbuf * msgp, size_t msgsize, long msgtype, int msgflg);

//Control Message
msgctl(int msqid, int cmd, struct msqid_ds *buf);


공유 메모리 (Shared Memory)

  • 어떠한 매개체를 통해 데이터를 주고 받는 것이 아니라 메모리 자체를 공유하기 때문에 불필요한 데이터 복사의 오버헤드가 발생하지 않아 가장 빠르며 같은 메모리 영역을 여러 프로세스가 공유하기 때문에 동기화가 필요
  • IPC 중에서 가장 빠른 통신 방법
  • 프로세스 간 사용하려면 메모리 크기가 동일해야 함
  • 사용 시기
    • 다른 프로세스와 양방향 통신 시
  • 통신 단위 : 구조체
  • 공유 매개체 : 메모리
  • 장점
    • 중개자 없음 → 곧바로 메모리에 접근 가능하기 때문에 속도가 빠름
  • 단점
    • 데이터를 읽어야 하는 시점 알 수 없음
    • 동기화 기술이 필요


공유메모리 실습 코드

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>

#define KEY 1234

int main()
{
        int shmid;
        int *num;
        void *memory_segment = NULL;

		//이미 공유 메모리가 생성되어 있는 경우
        if((shmid = shmget(KEY, sizeof(int), IPC_CREAT|0666)) == -1)
        {
                printf("shmget error\n");
                return -1;
        }

        printf("shmid : %d\n", shmid);

        if((memory_segment = shmat(shmid, NULL, 0)) == (void *)-1)
        {
                printf("shmat error\n");
                return -1;
        }

        num = (int *)memory_segment;
        (*num)++;
        printf("num : %d\n", (*num));

        return 0;
}

profile
하이루

0개의 댓글