Process ํ๋ก์ธ์ค ๊ฐ ํต์ ์ด๋ก
IPC: Inter-Process Communication
Cooperating ํ๋ ํ๋ก์ธ์ค๋ค์ IPC ๋ฉ์ปค๋์ฆ(๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๊ฒ)์ ํตํด ์๋ก ํต์ ํจ
IPC์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ
- ๋ฉ๋ชจ๋ฆฌ ๊ณต์ (a)
- ๋ฉ์์ง ์ ๋ฌ(b)
์์ฐ์ ์๋น์ ๋ฌธ์
์์ฐ์๋ ์ ๋ณด๋ฅผ ์์ฐ, ์๋น์๋ ์ ๋ณด๋ฅผ ์๋น (์๋ฅผ ๋ค์ด ์น ์๋ฒ๊ฐ HTML ํ์ผ์ ์์ฐ, ๋ธ๋ผ์ฐ์ ๊ฐ ์๋น ๋ฑ)
shared-memory ํตํ ํด๊ฒฐ ๋ฐฉ๋ฒ
- ์์ฐ์์ ์๋น์ ๋์์ ์คํ, buffer๋ฅผ ์ฌ์ฉํด ์์ฐ์๋ฅผ buffer๋ฅผ ์ฑ์ฐ๊ณ , ์๋น์๋ buffer๋ฅผ ๋น์. buffer๊ฐ ๊ฐ๋ ์ฐจ๋ฉด wait, ๋น์์ง๋ฉด ์ฑ์ฐ๊ธฐ ์์
- ๋ฌธ์ ์ : ํ๋ก๊ทธ๋๋จธ๊ฐ ์์์ ์ฝ๋๋ฅผ ์ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ share ํด์ผ
Message-Passing
- OS๊ฐ cooperating process๋ค์ ์ํ ์๋จ์ ์ ๊ณต
- send(message), receive(messsage) ๋ ๊ฐ์ system call๋ง ํ์
- ์๋์ ๊ฐ์ ๋ค์ํ Message-Passing ๋ฐฉ๋ฒ ์กด์ฌ
- ์ง์ /๊ฐ์
- ์ง์ ์ํต: ์๋ น์์ ๋ณด๋ด๋ ์์ ์ด๋ฆ ๋ช ํํ๊ฒ ์ ์. ์๋์ ์ผ๋ก communication link ์์ฑ. ํ๋์ link๋ง ๋ง๋ค์ด์ง (ex: send(P, message), receive(Q, message)-P๊ฐ ๋ณด๋ด๊ณ Q๊ฐ ๋ฐ๊ณ )
- ๊ฐ์ ์ํต: mailbox ๋๋ port๋ก๋ถํฐ ๋ฉ์์ง ๋ณด๋ด๊ณ ๋ฐ์. ํ ์์ process๋ค ์ฌ์ด์์ link ๋ง๋ค์ด์ง. ๋ ๊ฐ ์ด์์ process๋ค ์ฌ์ด์์ link๊ฐ ์กด์ฌํ ์ ์์. O/S๊ฐ mailbox ์์ฑ/message ์ ์ก,์ ๋ฌ/mailbox ์ญ์ ์ ๊ณตํ๋ฉด ๋จ (ex: send(A, message), receive(A, message)-๋ฉ์ผ ๋ฐ์ค์ ๋ณด๋ด๊ณ ๋ฉ์ผ ๋ฐ์ค๋ก๋ถํฐ ๋ฐ๊ณ )
- ๋๊ธฐํ(synchronous)/๋น๋๊ธฐํ(asynchronous)
- Blocking send: ๋ฉ์์ง๋ฅผ ๋ฐ์ ๋๊น์ง sender๊ฐ block ๋์ด ์์
- Non-blocking send: ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ณ ํ๋ ์ผ ํจ
- Blocking receive: ๋ฉ์์ง ๋ฐ์ ๋๊น์ง receiver๊ฐ block ๋์ด ์์
- Non-blocking receive: ๊ฐ๋ฅํ ๋ฉ์์ง๋ฅผ ๋ฐ๊ฑฐ๋ ์๋ฌด ๋ฉ์์ง๋ ๋ฐ์ง ์๊ฑฐ๋ ๋ ์ค์ ํ๋.๋๊ธฐํ: Blocking, ๋ค ๋ณด๋ด๊ณ ๋ค ๋ฐ์ ๋๊น์ง ๊ธฐ๋ค๋ฆผ
๋น๋๊ธฐํ: Non-blocking, ๋ค ๋ฐ์๋์ง ํ์ ํ ์ ์์. ์ผ๋จ ์๊ธฐ ์ผ ํจ
- ๊ทธ ์ธ์๋ ์๋/๋ช ์์ ๋ฒํผ๋ง ๋ฑ ๋ค์ํ ๋ฐฉ๋ฒ ์กด์ฌ
ํ๋ก์ธ์ค ๊ฐ ํต์ ์ค์ต
Shared Memory: POSIX Shared Memory
POSIX Shared Memory๋
POSIX๋ Portavle Operating System Interface(for Unix)์ ์ฝ์. meomoru-mapped file์ ์ด์ฉํด์ Shared Memory ์์ญ์ ๋ง๋ฆ.
POSIX Shared Memory์ Producer ๊ตฌํ
Shared Memory ๊ณต๊ฐ์ ๋ง๋ค๊ณ ๊ฑฐ๊ธฐ์ ๋ฉ์์ง๋ฅผ ์์ฑํ๋ ์ฝ๋
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 4096;
const char *name = "OS";
const char *message_0 = "Hello";
const char *message_1 = "Shared Memory!\n";
int shm_fd; //file discreptor
char *ptr;
/*shared memory ์์ฑ*/
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/*shared memory ์ฌ์ด์ฆ ๊ตฌ์ฑ*/
ftruncate(shm_fd, SIZE);
/*map the shared memory object*/
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
/*write to the shared memory*/
sprintf(ptr, "%s", message_0);
ptr += strlen(message_0);
sprintf(ptr, "%s", message_1);
ptr += strlen(message_1);
return 0;
}
๐์ฝ๋ ์ค๋ช
(1) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ฒด ์์ฑ
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
- shm_open(name, flags, mode)๋ฅผ ์ด์ฉํด์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ง๋ฆ.
-name์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์๋ณ์ ์ญํ ์ ํจ ("OS"๋ผ๋ ์ด๋ฆ ์ฌ์ฉ).- O_CREAT | O_RDWR: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ผ๋ฉด ์๋ก ๋ง๋ค๊ณ , ์ฝ๊ธฐ/์ฐ๊ธฐ ๋ชจ๋(O_RDWR)๋ก ์ผ.
- 0666: ํ์ผ ๊ถํ์ ์ค์ (์ฝ๊ธฐ/์ฐ๊ธฐ ํ์ฉ).
(2) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ ์์ฑ
ftruncate(shm_fd, SIZE);
- ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ SIZE = 4096 (4KB)๋ก ์ค์ .
- ์์ฑ๋ ๋ฉ๋ชจ๋ฆฌ์ ํฌ๊ธฐ๋ฅผ ftruncate()๋ก ๋ณ๊ฒฝํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ 0๋ฐ์ดํธ๋ผ ์ธ ์ ์์.
(3) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋งคํ
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
- PROT_READ | PROT_WRITE: ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ฐ๋ฅ.
- MAP_SHARED: ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ณต์ ๊ฐ๋ฅ.
(๐ค๋งคํ ๋ถ๋ถ์ด ์ข ์๋ฆฌ์ก ํด์ ์ฐพ์๋ณธ ๊ฐ ์ธ์์ ๊ตฌ์ฒด์ ์ญํ ...์ฐธ๊ณ ๋ฐ๋)
(4) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ ์ฐ๊ธฐ
sprintf(ptr, "%s", message_0); ptr += strlen(message_0); sprintf(ptr, "%s", message_1); ptr += strlen(message_1);
- sprintf(ptr, "%s", message_0);: "Hello" ์ ์ฅ.
- ptr += strlen(message_0): ํฌ์ธํฐ ์ด๋.
- sprintf(ptr, "%s", message_1);: "Shared Memory!\n" ์ ์ฅ.
POSIX Shared Memory์ Consumer ๊ตฌํ
์์ฑ๋ Shared Memory์ ๋ฌธ์์ด์ ์ฝ๋ Consumer ๊ตฌํ ์ฝ๋
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 4096;
const char *name = "OS";
const char *message_0 = "Hello";
const char *message_1 = "Shared Memory!\n";
int shm_fd; //file discreptor
char *ptr;
/*shared memory ์์ฑ*/
shm_fd = shm_open(name, O_RDONLY, 0666);
/*map the shared memory object*/
ptr = (char *)mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
/*read from the shared memory*/
printf("%s", (char *)ptr);
/*remove the shared memory*/
shm_unlink(name);
return 0;
}
๐ ์ฝ๋ ์ค๋ช
(1) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ด๊ธฐ
shm_fd = shm_open(name, O_RDONLY, 0666);;
- shm_open("OS", O_RDONLY, 0666);๋ฅผ ์ด์ฉํด์ ์ด๋ฏธ ์กด์ฌํ๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ๊ธฐ ๋ชจ๋๋ก ์ผ.
(2) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋งคํ
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
- mmap()์ ์ฌ์ฉํด ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋งคํ.
(3) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ดํฐ ์ถ๋ ฅ
printf("%s", (char *)ptr);
- ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋ ๋ฌธ์์ด์ ์ฝ์ด์ ์ถ๋ ฅ.
(4) ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ญ์
shm_unlink(name);
- shm_unlink("OS");๋ฅผ ํธ์ถํด์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ฑฐ.
- ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ฑฐํ์ง ์์ผ๋ฉด, ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์ด๋ ๋จ์ ์์ ์ ์์.
cf) ์ฐธ๊ณ ๋ก ์ฝ๋ ์คํ์ gcc [producer ํ์ผ ์ด๋ฆ.c] -lrt-> ./a.out-> gcc [consumer ํ์ผ ์ด๋ฆ.c] -lrt-> ./a.out ํด์ฃผ๋ฉด ์์ฑํ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ค.
Message Passing: Pipes
Pipes๋
UNIX์์ ์์ฃผ ์ด์ฐฝ๊ธฐ์ ์ฌ์ฉํ๋ ๋งค์ปค๋์ฆ. shared-memory์์ ๋ง๋ค๊ณ , ์ฐ๊ณ , ์ฝ๊ณ , ์ญ์ ํ๋ ๊ท์ฐฎ์ ๊ณผ์ ์ ๋ํ ํด๊ฒฐ์ฑ
. ์ผ๋ฐฉํฅ. ๋คํธ์ํฌ์์๋ ์ฌ์ฉํ์ง ์์. ๋คํธ์ํฌ์์๋ ๋์ socket ์ฌ์ฉ. Ordinary pipes, Named pipes๊ฐ ์์. Ordinary pipes์๋ง parent์ child ์ญํ ์์ผ๋ฉฐ ์ด๋ฒ ์ค์ต๋ Ordinary ๋ฒ์ . ๋ ๊ฐ์ pipe์ด ํ์. Parent์์ Child, Child์์ Parent.
๋ ๊ฐ์ ํ์ดํ pipe(int fd[])
- fd[0]: ์ฝ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ํ์ดํ
- fd[1]: ์ฐ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ํ์ดํ
Pipes ๊ตฌํ
Pipe๋ฅผ ํตํด ํ๋ก์ธ์ค๋ค์ด "read Greeting"์ ์ ๊ณ ์ฝ๋ ์ฝ๋ ๊ตฌํ
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1
int main()
{
char write_msg[BUFFER_SIZE] = "Greetings";
char read_msg[BUFFER_SIZE];
int fd[2];
pid_t pid;
/*ํ์ดํ ์์ฑ*/
pipe(fd);
pid = fork();
if (pid > 0) { //๋ถ๋ชจ ํ๋ก์ธ์ค์ค
close(fd[READ_END]);
/*ํ์ดํ์ ์ฐ๊ธฐ*/
write(fd[WRITE_END], write_msg, strlen(write_msg) +1);
close(fd[WRITE_END]);
}
else if (pid == 0) { //์์ ํ๋ก์ธ์ค์ค
close(fd[WRITE_END]);
/*ํ์ดํ ์ฝ๊ธฐ*/
read(fd[READ_END], read_msg, BUFFER_SIZE);
printf("read %s\n", read_msg);
close(fd[READ_END]);
}
return 0;
}
๐ ์ฝ๋ ์ค๋ช
(1) ํ์ดํ ์์ฑ
pipe(fd);
- fd[0]: ํ์ดํ์ ์ฝ๊ธฐ(read) ๋
- fd[1]: ํ์ดํ์ ์ฐ๊ธฐ(write) ๋
- pipe()๋ฅผ ํธ์ถํ๋ฉด ๋ ๊ฐ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ(fd ๋ฐฐ์ด)๊ฐ ์์ฑ๋จ
(2) ํ๋ก์ธ์ค ์์ฑ fork()
- fork()๋ฅผ ํธ์ถํ์ฌ ๋ถ๋ชจ์ ์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑ
- ๋ถ๋ชจ ํ๋ก์ธ์ค์ ์์ ํ๋ก์ธ์ค๋ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ณต์ ํ์ฌ ์คํ๋์ง๋ง, ๊ฐ๊ฐ ๋ ๋ฆฝ์ ์ธ ์คํ ํ๋ฆ์ ๊ฐ์ง
(3) ๋ถ๋ชจ ํ๋ก์ธ์ค (๋ฐ์ดํฐ ์ฐ๊ธฐ)
- close(fd[READ_END]); ๋ถ๋ชจ ํ๋ก์ธ์ค๋ ์ฐ๊ธฐ ์ ์ฉ์ด๋ฏ๋ก, ์ฝ๊ธฐ ๋์ ๋ซ์.
- write(fd[WRITE_END], write_msg, strlen(write_msg) + 1); "Greetings" ๋ฌธ์์ด์ ํ์ดํ์ ์ (+1์ ๋ฌธ์์ด ์ข ๋ฃ ๋ฌธ์ \0 ํฌํจ)
- close(fd[READ_WRITE_END]); ๋ฐ์ดํฐ๋ฅผ ๋ค ์ผ์ผ๋ฉด ํ์ดํ ๋ซ๊ธฐ
(4) ์์ ํ๋ก์ธ์ค (๋ฐ์ดํฐ ์ฝ๊ธฐ)
- close(fd[WRITE_END]); ์์ ํ๋ก์ธ์ค๋ ์ฝ๊ธฐ ์ ์ฉ์ด๋ฏ๋ก, ์ฐ๊ธฐ ๋์ ๋ซ์.
- read(fd[READ_END], read_msg, BUFFER_SIZE); ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ๋ณด๋ธ "Greetings"์ ์ฝ์ด read_msg์ ์ ์ฅ
- close(fd[READ_END]); ๋ฐ์ดํฐ๋ฅผ ๋ค ์ฝ์์ผ๋ฉด ํ์ดํ ๋ซ๊ธฐ