독립적인 프로세스들은 다른 프로세스의 실행에 영향을 주거나 받을 수 없다. 하지만 Cooperating 프로세스들은 다른 프로세스의 실행에 영향을 주거나 받을 수 있다. 여러 개의 프로세스/스레드(thread)가 동시에 작업을 진행하는 것이다.
이는
등의 이점을 준다.
IPC는 프로세스들이 통신하고 그들의 행위를 동기화하기 위한 매커니즘이다. 두 가지 방법이 존재한다.
#include <stdio.h>
#include <stlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main()
{
/* the size (in bytes) of shared memory object */
const int SIZE 4096;
/* name of the shared memory object */
const char *name = "OS";
/* strings written to shared memory */
const char *message_0 = "Hello";
const char *message_1 = "World!";
/* shared memory file descriptor */
int shm_fd;
/* pointer to shared memory object */
void *ptr;
/* Create the shared memory object */
shm_fd = shm_open(name, O_CREAT | O_RDRW, 0666);
/* configure the size of the shared memory object */
ftruncate(shm_fd, SIZE);
/* memory map the shared memory object */
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
/* write to the shared memory object */
sprintf(ptr, "%s", message_0);
ptr += strlen(message_0);
sprintf(ptr, "%s", message_1);
ptr += strlen(message_1);
return 0;
}
#include <stdio.h>
#include <stlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main()
{
/* the size (in bytes) of shared memory object */
const int SIZE 4096;
/* name of the shared memory object */
const char *name = "OS";
/* strings written to shared memory */
const char *message_0 = "Hello";
const char *message_1 = "World!";
/* shared memory file descriptor */
int shm_fd;
/* pointer to shared memory object */
void *ptr;
/* Create the shared memory object */
shm_fd = shm_open(name, O_RDONLY, 0666);
/* memory map the shared memory object */
ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
/* read from the shared memory object */
printf("%s", (char*)ptr);
/* remove the shared memory object */
shm_unlink(name);
return 0;
}
위와 같은 방식으로 공유된 메모리를 통해 프로세스끼리 통신할 수 있다. 사용된 함수는 모두 System call 함수이다.
메시지 전달 방식은 프로세스들이 같은 주소의 공간을 공유하지 않고 통신한다. IPD (message passing) 도구는 두 가지의 오퍼레이션을 제공한다
만약 P와 Q가 통신하길 원한다면, 다음과 같은 것이 필요하다.
메시지 전달 시스템을 디자인하는 데에는 다음과 같은 이슈들이 존재한다. 차례대로 하나씩 살펴보도록 하자.
메시지 전달은 blocking 또는 non-blocking일 수 있다.
Blocking은 동기적이다.
Non-blocking은 비동기적이다.
Blocking send: 메시지를 보내는 프로세스는 메시지가 메시지를 받는 프로세스나 사서함에 보내지기 전까지 동작하지 않는다.
Non-blokcing send: 메시지를 보내는 프로세스는 메시지를 보내고 오퍼레이션을 다시 시작한다.
Blocking receive: 메시지가 유효하기 전까지 동작하지 않는다.
Non-blocking receive: 유효한 메시지든 아니든 계속 동작한다.
메시지 큐가 링크에 붙어 있다. 일종의 데이터 보관함이다. 세 가지 방법 중 하나로 구현된다.
Inter-Process Communication은 여러 프로세스들이 그들 사이에서 통신하기 위한 매커니즘이다. 다른 프로세스들은 다른 주소 공간에서 동작한다. 따라서 운영체제는 통신하기 위한 매커니즘을 제공해야 하는데, 이것이 IPC이다.
UNIX에서의 IPC 타입들은 다음과 같다. system V IPC는 전통적 IPC를 사용할 수 있다.
파이프(pipe)는 한 프로세스를 다른 프로세스로 연결하는 단방향의 byte 스트림이다.
파이프 매커니즘의 현재 사용 중 하나는 커맨드들이 연결될 때 커맨드 라인 인터프리터의 수단으로써 수행되는 것이다.
프로세스에 의해 생성된, 그리고 연관된 descriptor 사이에서의 전달은 parend-child(조상과 자손) 사이에서만 가능하다.
혹은 파이프의 생성자를 공통된 조상으로 하는 프로세스들 사이에서의 통신만 제한적으로 가능하다.
anonymous pipe의 생성
int pipe(int filesdes[2]);
#include <stdio.h>
#include <unistd.h>
int main(void){
/* fd[0] is for read, fd[1] is for write */
inr n, fd[2], pid; char line[100];
if(pipe(fd) < 0) exit(-1); // make pipe
if((pid == fork()) < 0) exit(-1);
else if(pid > 0) { /* parent */
close(fd[0]);
write(fd[1], "Hello, World\n", 12);
wait(NULL) //wait child
}
else { /* child */
close(fd[1]);
n = read(fd[0], line, MAXLINE);
write(STDOUT_FILENO, line, n);
}
}
anonymous 파이프의 제약이 named 파이프에서는 없다. 왜냐하면 그들의 엔트리들은 파일 시스템에 존재하기 때문이다. 커널 안의 메모리에 파일을 만든 개념이라고 생각할 수 있다.
이름을 가지고 파일처럼 다루어진다. (e.g., open, close, read, write)
mkfifo
또는 mknod
로 생성된다.int mkfifo(const char *path, mode_t mode);
read()
그리고 write()
시스템 콜을 사용하면 된다.