IPC기법 정리

IPC 기법관련 시스템콜 사용법 이해

파이프

파이프를 통한 부모 -> 자식 간 단방향 통신

예제

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
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MSGSIZE 255

char* msg = "Hello Child Process!";
int main() {
char buf[255];
int fd[2], pid, nbytes;
if (pipe(fd) < 0) // pipe(fd) 로 파이프 생성
exit(1);
pid = fork(); // 이 함수 실행 다음 코드부터 부모/ 자식 프로세스로 나뉘어짐
if (pid >0) { // 부모 프로세스에는 자식 프로세스 pid 값이 들어감
printf("parent PID:%d, child PID%d\n", getpid(), pid);
write(fd[1], msg, MSGSIZE); // fd[1] 에 씁니다.
exit(0);
}
else { // 자식 프로세스에는 pid 값이 0이 됨.
printf("child PID: %d\n", getpid());
nbytes = read(fd[0], buf, MSGSIZE); // fd[0] 으로 읽음
printf("%d %s\n", nbytes, buf);
exit(0);
}
return 0;
}

메시지 큐(message queue)

FIFO 정책을 데이터 전송.

전송하는 코드

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
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>

typedef struct msgbuf {
long type;
char text[50];
} MsgBuf;

int main(void) {
int msgid, len;
MsgBuf msg;
key_t key = 1234;
msgid = msgget(key, IPC_CREAT|0644);
if(msgid == -1) {
perror("msgget");
exit(1);
}
msg.type = 1;
strcpy(msg.text, "Hello Message Queue\n");
if(msgsnd(msgid, (void *)&msg, 50, IPC_NOWAIT) == -1) {
perror("msgsnd");
exit(1);
}
return 0;
}
  • 동일한 key를 사용해야 함.
  • msgget 으로 msgid 를 얻음.
  • msgsnd 으로 큐에 메세지 전송

받는 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct msgbuf {
long type;
char text[50];
} MsgBuf;

int main(void) {
MsgBuf msg;
int msgid, len;
key_t key = 1234;
if((msgid = msgget(key, IPC_CREAT|0644))<0) {
perror("msgget");
exit(1);
}
len = msgrcv(msgid, &msg, 50, 0, 0);
printf("Received Message is [%d] %s\n", len, msg.text);
return 0;
}
  • 동일한 key 사용
  • msgid 를 얻음
  • msgrcv를 통해 메세지큐에 데이터 받음.

공유 메모리(shared memory)

커널 공간에 메모리 공간을 만들고, 해당 공간을 변수처럼 쓰는 방식. mesage queue 처럼 FIFO 방식이 아니라, 해당 메모리 주소를 마치 변수처럼 접근하는 방식이다. 공유 메모리 key를 가지고 여러 프로세스가 접근 가능하다.

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
31
32
33
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void) {
int shmid, pid;
char *shmaddr_parent, *shmaddr_child;
shmid = shmget((key_t)1234, 10, IPC_CREAT|0644);
if(shmid == -1) {
perror("shmget error\n");
exit(1);
}
pid = fork();
if (pid >0) {
wait(0);
shmaddr_parent = (char *)shmat(shmid, (char *)NULL, 0);
printf("%s\n", shmaddr_parent);
shmdt((char *)shmaddr_parent);
}
else {
shmaddr_child = (char *)shmat(shmid, (char *)NULL, 0);
strcpy((char *)shmaddr_child, "Hello Parent!");
shmdt((char *)shmaddr_child); // 해당 프로세스에서 메모리에 올라간 변수 삭제
exit(0);
}
shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL); // 공유 메모리에서 삭제
return 0;
}