티스토리 뷰

반응형

서로다른 Process간에 통신을 하기위해서는 IPC, RPC등의 기법들을 이용해야하는데 이번 포스팅에서는 IPC기법에는 어떤 것들이 있고, 각자 사용되는 상황 및 특징들을 살펴보겠다.

 

<종류>

1. Anonymous PIPE (익명 파이프)

2. Named PIPE

3. Message Queue

4. Shared Memory

5. Socket - 해당 포스트에서는 따로 다루지 않습니다. 워낙 뭐.. ㅎㅎ

6. ..... 

 

위 5개는 확실하게 알고가자!!

 


 

1. Anonymous PIPE

  - 외부 프로세스에서는 이 파이프에 접근이 불가능하다.

    But, fork등의 방법으로 자식프로세스가 태어난 경우에는 File Descriptor를 상속받아 통신가능.

 

 int fd[2];

 rc = pipe(fd);0번 index에는 stdin, 1번 index에는 stdout의 stream이 할당된다.

   ( Return값이 0보다 커야 정상. )

 

  - 특수한 경우에는 최고의 간단한 구성. 

    그러나 적용가능한 범위가 굉장히 제한적이다.

  - PIPE에 Data가 들어가는 순간, 주인없는 Data가 된다.

  - 양방향 통신을 위해서라면 두개의 파이프가 필요하다. 하나로는 절대안됌!!

 

 

 

2. Named PIPE

  - Anonymous PIPE의 한계인 외부프로세스와의 통신을 위한 파이프.

    ( mkfifo, mknod를 통해 pipe 파일을 생성하고, 그 파일을 통해 통신 )

 

 

int fd = open("./pipe_name", O_WRONLY);

write(fd, Buffer, sizeof(Buffer));

 

---------------------------------------------------

 

access("./pipe_name", O_OK)  →  unlick("./pipe_name");

rc = mkfifo("./pipe_name", 0666);

int fd = open("./pipe_name", O_RDWR);

read(fd, Buffer, sizeof(Buffer));

 

 

 

각각 프로세스에서 위와같이 구성을하게되며 mkfifo는 반드시 한쪽에서만 해줘야한다.

 

  - 하나의 파이프를 통해 양방향 통신이 가능은하다.

    그러나, PIPE에 들어가는순간 임자없는 데이터가되고 넣은애가 도로 꺼내갈수도있다.

    그러므로 그냥 속편하게 두개의 PIPE를 사용하는 것이 낫다.

 

 

 

3. Message Queue

  - 어디에서든 Message를 꺼낼수 있는 공간. 즉, 메모리공간을 이용해 통신한다.

  - 데이터에 Message번호를 붙여서 서로를 인식할 수 있다.

  - 사용자가 임의로 만든 구조체를 단위로 데이터를 송/수신한다.

        ( 해당 구조체는 송/수신하는 두군데에 전부 정의해줘야한다. )

 

 

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

 

int msgget(key_t key, int msgflg);

int msgsnd(int msgid, const void* msgp, size_t msgsz, int msgflg);

ssize_t msgrcv(int msgid, void* msgp, size_t msgsz, long msgtyp, int msgflg);

 

구현.

 

typedef struct{

   long msgtype;

   char msg_text[100];

}Msg; 

 → 구조체를 통해 메세지를 구성하게되는데 long msgtype만 고정이고 나머진 자유롭게 구성.

 

key_t key = 4449;

int que_id = msgget(key, IPC_CREAT | 0666);

  → 여기서 key값을 통해 해당 Queue를 생성(?)한다.

         ( 연결이라는 표현이 적절할지도..? )

      즉, 반드시 메세지를 주고받으려는 프로세스들끼리 일치시켜줘야한다.

 

Msg msg;

int msg_size = 0;

msg.msgtype = 10831; → 이것도 반드시 일치시켜줘야한다.

                                   이건 해당 큐에서도 메세지의 종류를 여러개로 세분화하기위함 !!

strcpy(msg.msg_text, "ch4njun's data");

msg_size = sizeof(msg) - sizeof(msg.msgtype);

  → msg의 크기는 반드시 long msgtype의 크기를 제외한 크기여야한다.

msgsnd(que_id, &msg, msg_size, 0);

 

꺼내는건 !

msgrcv(que_id, &msg, msg_size, 10831, IPC_NOWAIT);

 

msgctl(que_id, [ FLAG ], struct msqid_ds* buf);

  - IPC_STAT, IPC_SET, IPC_RMID

    ( IPC_RMID는 해당 Message Queue를 삭제한다. 떄문에 3번째 파라미터는 NULL )

 

 

 

 

 

4. Shared Memory

  - 공유메모리가 데이터자체를 공유하도록 지원.

  - 기본적으로 모든 프로세스는 자신만의 메모리 영역을 가진다. 그리고 그 영역은 커널로부터 보호되어진다. 다른 프로세스에서 함부로 그 메모리 영역에 접근하지 못하도록 보호되어진다. 이 때 PIPE와 같이 STREAM이 아니라 메모리자체를 공유하고 싶다면 커널에 요청하면 커널은 해당 프로세스에 공유 메모리 공간을 할당해준다. 이 메모리는 모든 프로세스가 중계자(커널)없이 접근이 가능해 IPC들 중에서 가장 빠르게 동작한다.

 

 

 

int shmid = shmget((key_t)1234, 1024, IPC_CREAT | 0666);

  → Key, Size 둘다를 반드시 양쪽에서 동일하게 해줘야 한다... (솔직히 size는 TMI긴해)

void* shmaddr = shmat(shmid, (void*)0, 0);

  → shmaddr 이라는 Stack변수에 공유메모리할당받은 주소를 저장하는거지.

      그리고 그 주소에 shmaddr이라는 Stack변수를 통해서 접근하는거야 !

strcpy((char*)shmaddr, "ch4njun's data");

shmdt(shmaddr);

 

" 반드시 SIGINT시 공유메모리 해제 Handler를 설치해야한다. " - maybe...

 

int shmid = shmget((key_t)1234, 1024, IPC_CREAT | 0666);

void* shmaddr = shmat(shmid, (void*)0, 0);

printf("%s\n", (char*)shmaddr);

shmdt(shmaddr);

 

공유메모리를 제거하고 싶을 땐,

shmdt(shmaddr); 을 통해 해당 프로세스에서 공유메모리를 분리하고.

shmctl(shmid, IPC_RMID, 0); 명령을 통해서 제거하면된다.

 

 

 

반응형

'운영체제(OS)' 카테고리의 다른 글

[OS] 다중 처리기 스케줄링  (0) 2019.11.04
[OS] CPU Scheduling 기본 ( 6가지 )  (0) 2019.11.04
[OS] CPU Scheduling  (0) 2019.09.30
[OS] Process Synchronized  (0) 2019.09.07
[OS] Thread  (0) 2019.09.07
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함