PIPE (파이프)
fork() 시스템 콜을 호출하면 새로운 프로세스를 복제하는데 굳이 왜 그렇게 하는 것이지?
fork()의 리턴 값은 정수형을 반환한다.
- 부모 프로세스 : 프로세스 ID
- 자식 프로세스 : 0
char * msg = "Hello Child Process";
int main(int argc, char const *argv[])
{
/* code */
char buf[255];
int fd[2], pid, nbytes;
if (pipe(fd) < 0) //pipe(fd) 로 파이프 생성
{
/* code */
exit(1);
}
pid = fork(); // 이 함수 실행 다음 코드부터 부모/자식 프로세스로 나뉘어짐
if (pid > 0) // 부모 프로세스는 pid에 실제 프로세스 ID가 들어감
{
/* code */
write(fd[1], msg, MSGSIZE); // fd[1] 에 씁니다.
exit(0);
}else { // 자식 프로세스는 pid가 0이 들어간다.
mbytes = read(fd[0], buf, MSGSIZE); //fd[0] 으로 읽음
printf("%d %s\n", nbytes, buf);
exit(0);
}
return 0;
}
부모 프로세스에서 write를 하고 자식 프로세스에서는 read를 하는 점에 주목하자!😀
(msg -> buf)
다른 프로세스임에도 불구하고 서로 통신을 한다는 점이 핵심이다.
기본 파이프는 단방향 통신이다.
fork()로 자식 프로세스를 만들었을 때, 부모와 자식 간의 통신이 시작된다.
메시지 큐 (Message queue)
기본은 FIFO 정책으로 데이터를 전송한다.
http://www.stoimen.com/2017/09/14/data-structures-infographic-stack-queue/
A Process
msqid = msgget(key, msgflg);
msgsnd = (msqid, &sbuf, buf_length, IPC_NOWAIT);
특별한 key를 생성하여 메시지 큐에 담고 sbuf에 넣어 msgsnd함수를 이용하여 큐에 INSERT 한다.
B Process
msqid = msgget(key, msgflg);
msgsnd = (msqid, &rbuf, MSGSZ, 1, 0);
동일한 key를 사용하여 해당 큐의 msgid를 얻을 수 있다.
파이프와 메시지 큐의 차이점
파이프와는 다르게 메시지 큐는 fork() 시스템 콜이 필요 없다. (key 값만 동일하면 된다.)
파이프와는 다르게 메시지 큐는 양방향 통신이 가능하다.
IPC 기법과 커널 모드
파이프, 메시지 큐 모두 커널 공간의 메모리를 사용한다.
공유 메모리
노골적으로 커널 공간에 공유할 수 있는 메모리 공간을 만들고 해당 공간을 변수처럼 사용하는 방식
공유 메모리 Key를 가지고 해당 메모리에 여러 프로세스가 접근이 가능하다.
'CS > O.S' 카테고리의 다른 글
(운영체제) DeadLock & Starvation (0) | 2020.04.16 |
---|---|
(운영체제) Thread의 개념 (0) | 2020.04.05 |
(운영체제) 프로세스간 커뮤니케이션 (0) | 2020.03.17 |
(운영체제) 프로세스와 컨텍스트 스위칭 (0) | 2020.03.17 |
(운영체제) 프로세스 구조와 힙 (0) | 2020.03.07 |