CS โ ipc followup
๐ 05/13 โ IPC ๋ชจ์๋ฉด์ ๊ผฌ๋ฆฌ์ง๋ฌธ ์ ๋ฆฌ
22_ipc.md๋ชจ์๋ฉด์ ์งํ ๋์จ ํ์ ์ง๋ฌธ 1๊ฐ๋ฅผ ๊น์ด ์๊ฒ ์ ๋ฆฌํ ๋ ธํธ. ๋ณธ๋ฌธ์ 22๋ฒ ์๋ณธ์ ํด๋น ์น์ ์ ๊ฐ๋ฆฌํค๊ณ , ์ฌ๊ธฐ์๋ ๊ฒฐ๋ก โ ํ๋ฆ โ ํ โ ์ฝ๋/์ โ ๋ฉด์ ๋ต๋ณ ํ ์ค ์์ผ๋ก ์์ถํ๋ค.
๋ชฉ์ฐจ
1. ์์ผ์ด๋ ๋ฌด์์ผ๊น
ํ ์ค ๊ฒฐ๋ก โ ์์ผ(socket)์ ๋คํธ์ํฌ ๋๋ ๊ฐ์ ๋จธ์ ์์์ ๋ endpoint๋ฅผ ์๋ ์๋ฐฉํฅ ํต์ ์ฑ๋์ ์ถ์ํ์ด๊ณ , OS๊ฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ(file descriptor) ๋ก ๋ ธ์ถํ๋ IPC/๋คํธ์ํฌ ํตํฉ ์ธํฐํ์ด์ค๋ค. 22๋ฒ IPC ยง10์ ์นดํ๋ก๊ทธ๋ฅผ ํ ํญ๋ชฉ์ฉ ๋ ํ์ด๋ณด๋ฉด, ์์ผ์ ๊ฐ์ ๋จธ์ IPC(UNIX domainยทloopback)๋ถํฐ ๊ธ๋ก๋ฒ ๋คํธ์ํฌ ํต์ (TCP/UDP)๊น์ง ๊ฐ์ API(BSD socket)๋ก ๋ค๋ฃจ๋ ๊ฐ์ฅ ๋ฒ์ฉ์ ์ธ ๋ฉ์ปค๋์ฆ์ด๋ค.
1-1. ์ ์ โ endpoint + fd ์ถ์ํ
1
2
3
4
ํ๋ก์ธ์ค A โโโ[์๋ฐฉํฅ ์ฑ๋]โโโ ํ๋ก์ธ์ค B
โ โ
์์ผ 1 ์์ผ 2
(fd: 4) (fd: 5)
์์ผ์ ๋ ๊ฐ์ง ๋ณธ์ง:
| ์ธก๋ฉด | ์๋ฏธ |
|---|---|
| endpoint (์ข ์ ) | ํต์ ์ ํ์ชฝ ๋. ๊ฐ ํต์ ๋ง๋ค ๋ณด๋ด๋ ์์ผ + ๋ฐ๋ ์์ผ = 2๊ฐ |
| file descriptor ์ถ์ํ | OS๋ ์์ผ์ ์ ์ fd๋ก ๋
ธ์ถ โ read/write/close๊ฐ ๊ทธ๋๋ก ๋์ (POSIX์ โeverything is a fileโ ์ฒ ํ) |
SOCKET ํ์
์ Windows์์ 32/64๋นํธ ์ ์ ํธ๋ค, POSIX์์ int fd. ๊ทธ๋์ ํ์ค ์
์ถ๋ ฅ(stdin/stdout)ยทํ์ผยทํ์ดํยท์์ผ์ด ๋ชจ๋ ๊ฐ์ API๋ก ๋ค๋ค์ง๋ค.
1
2
3
4
5
6
7
// POSIX โ ํ์ผ๊ณผ ์์ผ ๋ชจ๋ ๊ฐ์ read/write
int fd = open("file.txt", O_RDONLY);
read(fd, buf, sizeof(buf));
int sock = socket(AF_INET, SOCK_STREAM, 0);
// ... connect ํ
read(sock, buf, sizeof(buf)); // ๊ฐ์ read()!
์ด๊ฒ BSD socket API์ ์๋ํ ๋์์ธ โ ํต์ ์ ํ์ผ I/O์ ๋๊ฐ์ด ๋ค๋ฃจ๊ฒ ํ๋ค.
1-2. ํ๋ฆ ํ๋์ โ BSD socket API
1
2
3
4
5
6
7
8
9
10
11
12
์๋ฒ ์ธก ํด๋ผ์ด์ธํธ ์ธก
โโโโ โโโโ
socket() โ fd ์ป๊ธฐ socket()
bind() โ ์ฃผ์ ๋ถ์ฌ
listen() โ ๋ค์ด์ค๋ ์ฐ๊ฒฐ ๋๊ธฐ
connect() โ ์ฐ๊ฒฐ ์๋
accept() โ ์ ์ฐ๊ฒฐ ์๋ฝ โโโโโโโโโโโโโ
(์ ์์ผ fd ๋ฐํ)
โ โ
send/recv โโโโโโโ์๋ฐฉํฅโโโโโโ send/recv
โ โ
close() close()
๊ฐ ๋จ๊ณ ์๋ฏธ:
| ํจ์ | ์๋ฏธ |
|---|---|
socket(family, type, proto) | ์ ์์ผ fd ์์ฑ. ๊ฐ์กฑยทํ์ ยทํ๋กํ ์ฝ ์ง์ |
bind(fd, addr, addrlen) | ์์ผ์ ์ฃผ์(IP+ํฌํธ ๋๋ ๊ฒฝ๋ก) ๋ถ์ฌ. ์๋ฒ ํ์ |
listen(fd, backlog) | TCP ์๋ฒ โ ์ฐ๊ฒฐ ๋๊ธฐ ์ํ๋ก. backlog๋ ๋ฏธ์๋ฝ ํ ๊น์ด |
accept(fd, ...) | ํ์์ ์ฐ๊ฒฐ ํ๋ ๊บผ๋ด ์ fd ๋ฐํ. ์ฐจ๋จํ |
connect(fd, addr, addrlen) | ํด๋ผ์ด์ธํธ โ ์๋ฒ์ ์ฐ๊ฒฐ ์๋ |
send/recv ๋๋ write/read | ๋ฐ์ดํฐ ์ก์์ |
close(fd) | ์์ผ ๋ซ์. TCP๋ 4-way handshake |
1-3. ์ข ๋ฅ โ Stream vs Datagram
1
2
3
4
5
6
7
8
9
10
11
SOCK_STREAM (TCP):
๋ฐ์ดํธ ์คํธ๋ฆผ / ์ฐ๊ฒฐ ์งํฅ / ์ ๋ขฐ์ฑ / ์์ ๋ณด์ฅ
โ ๊ฐ์ ์ฑ๋๋ก 4๋ฐ์ดํธ + 8๋ฐ์ดํธ ์ฐ๋ฉด 12๋ฐ์ดํธ๋ก ํ ๋ฒ์ ๋ฐํ ์ ์์ (๋ฉ์์ง ๊ฒฝ๊ณ ์์)
SOCK_DGRAM (UDP):
๋ฉ์์ง ๋จ์ / ๋น์ฐ๊ฒฐ / ๋น์ ๋ขฐ / ์์ ๋ณด์ฅ ์์
โ 4๋ฐ์ดํธ ํจํท + 8๋ฐ์ดํธ ํจํท โ 4๋ฐ์ดํธ, 8๋ฐ์ดํธ๋ก ๋ฐ๋ก ๋ฐ์ (๊ฒฝ๊ณ ๋ณด์กด)
SOCK_RAW:
IP ํค๋๋ถํฐ ์ง์ โ ๋ณดํต ๊ด๋ฆฌ์ ๊ถํ ํ์
โ ping, traceroute, ํจํท ์บก์ฒ
| ํ์ | ์ฐ๊ฒฐ | ์ ๋ขฐ์ฑ | ์์ | ๋ฉ์์ง ๊ฒฝ๊ณ | ๋น์ฉ | ์ฌ์ฉ์ฒ |
|---|---|---|---|---|---|---|
SOCK_STREAM (TCP) | O | O (์ฌ์ ์ก) | O | X | ํธ๋์ ฐ์ดํฌ + ACK | HTTPยทSSHยทDB |
SOCK_DGRAM (UDP) | X | X | X | O | ๋จ์ ์ก์์ | DNSยท๊ฒ์ยท์คํธ๋ฆฌ๋ฐ |
SOCK_SEQPACKET | O | O | O | O | ์ค๊ฐ | ํน์ (์ ์ ์) |
SOCK_RAW | - | - | - | - | - | ํจํท ์กฐ์ยท์ง๋จ |
1-4. ์ฃผ์ ํจ๋ฐ๋ฆฌ (family)
1
2
3
4
5
AF_INET โ IPv4 (32๋นํธ IP + 16๋นํธ port)
AF_INET6 โ IPv6 (128๋นํธ IP + 16๋นํธ port)
AF_UNIX โ UNIX domain (ํ์ผ ์์คํ
๊ฒฝ๋ก, ๊ฐ์ ๋จธ์ )
AF_BLUETOOTH โ Bluetooth
AF_PACKET โ ๋งํฌ ๊ณ์ธต (Linux, ํจํท ์บก์ฒ)
1
2
3
4
5
6
7
8
9
10
11
12
// IPv4 TCP
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(8080),
.sin_addr.s_addr = inet_addr("127.0.0.1")
};
// UNIX domain
struct sockaddr_un addr = {
.sun_family = AF_UNIX
};
strcpy(addr.sun_path, "/tmp/mysock");
| ํจ๋ฐ๋ฆฌ | ์ฃผ์ | ๋ฒ์ |
|---|---|---|
AF_INET | IPv4 + port | ๊ฐ์ ๋จธ์ (loopback) + ๋คํธ์ํฌ |
AF_INET6 | IPv6 + port | ๊ฐ์ ๋จธ์ + ๋คํธ์ํฌ |
AF_UNIX | ํ์ผ ๊ฒฝ๋ก | ๊ฐ์ ๋จธ์ ๋ง (๊ฐ์ฅ ๋น ๋ฆ) |
1-5. 5-tuple โ ์ฐ๊ฒฐ์ ์๋ณ์
TCP ์ฐ๊ฒฐ ํ๋๋ 5-tuple๋ก ์ ์ผํ๊ฒ ์๋ณ๋๋ค:
1
2
3
(protocol, src_ip, src_port, dst_ip, dst_port)
์: (TCP, 192.168.1.10:54321, 93.184.216.34:80)
๊ฐ์ ์๋ฒ IPยทํฌํธ์ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ๋์ ์ ์ํด๋, ํด๋ผ์ด์ธํธ ์ธก ํฌํธ(ephemeral port, OS๊ฐ ์๋ ํ ๋น)๊ฐ ๋ค๋ฅด๋ฏ๋ก 5-tuple์ด ๋ชจ๋ ๋ค๋ฅด๋ค โ ์ปค๋์ด ๊ฐ ์ฐ๊ฒฐ์ ๋ถ๋ฆฌ ๊ด๋ฆฌ ๊ฐ๋ฅ.
1
2
3
4
์๋ฒ 192.168.1.10:80
โโ (TCP, 1.2.3.4:54321, 192.168.1.10:80) โ ์ฐ๊ฒฐ 1
โโ (TCP, 1.2.3.4:54322, 192.168.1.10:80) โ ๊ฐ์ IP์ ๋ค๋ฅธ ephemeral port
โโ (TCP, 5.6.7.8:39101, 192.168.1.10:80) โ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ
์ด๊ฒ ํ ์๋ฒ๊ฐ ์์ญ๋ง ๋์ ์ฐ๊ฒฐ์ ๋ฐ์ ์ ์๋ ์๋ฆฌ.
1-6. UNIX domain socket โ ๊ฐ์ ๋จธ์ IPC
22๋ฒ ยง10.2์ ํต์ฌ ์ฌ์ ๋ฆฌ. ํ์ผ ์์คํ ๊ฒฝ๋ก๋ก ์๋ณ๋๊ณ , TCP loopback๋ณด๋ค 30~50% ๋น ๋ฅด๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ์๋ฒ
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strcpy(addr.sun_path, "/tmp/mysock");
unlink("/tmp/mysock"); // ์ด์ ์์กด ํ์ผ ์ ๊ฑฐ
bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sfd, 5);
int cfd = accept(sfd, NULL, NULL);
// ํด๋ผ์ด์ธํธ
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strcpy(addr.sun_path, "/tmp/mysock");
connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
write(sfd, "hello", 5);
ํน์ง:
- ํ์ผ ์์คํ
๊ฒฝ๋ก ์๋ณ โ
/tmp/mysock,/var/run/docker.sock - ๊ถํ ๊ด๋ฆฌ โ
chmod/chown๊ทธ๋๋ก ์ ์ฉ. ACL์ด OS ์ ๊ณต - TCP๋ณด๋ค ๋น ๋ฆ โ ํ๋กํ ์ฝ ์คํ(ํค๋ยท์ฒดํฌ์ฌยท์ํ์ค) ์ฐํ
- fd ์ ์ก ๊ฐ๋ฅ โ
SCM_RIGHTS๋ก ํ์ผ ๋์คํฌ๋ฆฝํฐ ์์ฒด๋ฅผ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ ๋ฌ (๊ณ ๊ธ) - abstract socket (Linux) โ
\0๋ก ์์ํ๋ ์ด๋ฆ์ผ๋ก ํ์ผ ์์คํ ๋ ธ๋ ์์ด ์ฌ์ฉ
๋ํ ์ฌ์ฉ์ฒ:
- Docker daemon (
/var/run/docker.sock) - X11/Wayland ๋์คํ๋ ์ด ์๋ฒ
- systemd activationยทjournald
- DBus ๋ฐ์คํฌํฑ IPC
1-7. loopback (127.0.0.1) vs UNIX domain
๊ฐ์ ๋จธ์ ์์์ TCP๋ฅผ ์ธ ๋ 127.0.0.1(IPv4 loopback) ๋๋ ::1(IPv6 loopback)์ ์ด๋ค. ์ปค๋์ด NIC๋ฅผ ์ฐํํด ์ง์ ์ฒ๋ฆฌ.
| ํญ๋ชฉ | loopback (127.0.0.1 + TCP) | UNIX domain (AF_UNIX) |
|---|---|---|
| ์ฃผ์ | 127.0.0.1:port | /tmp/mysock (๊ฒฝ๋ก) |
| ํ๋กํ ์ฝ ์คํ | TCP/IP ํต๊ณผ (ํค๋ยท์ฒดํฌ์ฌ) | ์ฐํ (์ปค๋ ์ง์ ํ) |
| ์๋ | UNIX domain์ 70% | 100% (๊ธฐ์ค) |
| ๋ฒํผ๋ง | ํผ (TCP ์๋์ฐ) | ์์ (์ปค๋ ๋ด ๋ฒํผ) |
| fd ์ ์ก | X | O (SCM_RIGHTS) |
| ์ ๊ทผ ์ ์ด | ๋ฐฉํ๋ฒฝ ๊ท์น | ํ์ผ ์์คํ ๊ถํ |
| ๋คํธ์ํฌ ํ์ฅ | ๊ฐ์ ์ฝ๋๋ก ์ธ๋ถ ๊ฐ๋ฅ | ๊ฐ์ ๋จธ์ ๋ง |
| ํฌํธ ์ถฉ๋ | 65535๊ฐ ํ์ | ๋ฌด๊ด (๊ฒฝ๋ก) |
๊ฒฐ๋ก โ ๊ฐ์ ๋จธ์ ์์์ IPC๋ง ํ์ํ๋ฉด UNIX domain์ด ๋น ๋ฅด๊ณ ๊ถํ ๊ด๋ฆฌ ์ฌ์. ๋คํธ์ํฌ ํ์ฅ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฉด ์ฒ์๋ถํฐ TCP. Docker๊ฐ UNIX domain socket์ ์ฐ๋ ์ด์ โ ๋คํธ์ํฌ ๋ ธ์ถ ์ํ ์์ด ํ์ผ ๊ถํ์ผ๋ก ์ ๊ทผ ์ ์ด.
1-8. Windows Winsock โ BSD socket์ Windows ๋ณํ
1
2
3
4
5
6
7
8
9
10
11
12
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa); // โ Windows๋ง ํ์
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// ... bind/connect/send/recv ๋์ผ
closesocket(s); // โ close()๊ฐ ์๋๋ผ closesocket()
WSACleanup();
POSIX์์ ์ฐจ์ด:
| ํญ๋ชฉ | POSIX | Windows Winsock |
|---|---|---|
| ์ด๊ธฐํ | ์์ | WSAStartup ํ์ |
| ์ข ๋ฃ | ์์ | WSACleanup |
| fd ํ์ | int | SOCKET (์ ์ ํธ๋ค) |
| ๋ซ๊ธฐ | close(fd) | closesocket(s) |
| ์๋ฌ | errno | WSAGetLastError() |
| non-blocking | fcntl(F_SETFL, O_NONBLOCK) | ioctlsocket(FIONBIO) |
| ๊ณ ์ฑ๋ฅ ๋น๋๊ธฐ | epoll / kqueue | IOCP (I/O Completion Port) |
| AF_UNIX | ํ์ค | Windows 10 1803+ ์ง์ (์ด์ ์ named pipe๋ก ๋์ฒด) |
Winsock์ IOCP๋ ๊ณ ์ฑ๋ฅ ์๋ฒ์ ์ฌ์ค์ ํ์ค โ WSARecv/WSASend + completion port๋ก ์์ญ๋ง ๋์ ์ฐ๊ฒฐ ์ฒ๋ฆฌ. Linux์ epollยทBSD์ kqueue์ ๊ฐ์ ์ญํ .
1-9. IPC ๊ด์ ์์ ๋ณธ 22๋ฒ๊ณผ์ ์์น
22๋ฒ ยง3 ๋ถ๋ฅ ํ๋ฅผ ๋ค์ ์ ์ฉ:
| ๋ฉ์ปค๋์ฆ | ๋ฐ์ดํฐ/์ ํธ | ์ปค๋ ๊ฒฝ์ | ๋คํธ์ํฌ |
|---|---|---|---|
| UNIX domain socket | ๋ฐ์ดํฐ | ๋งค๋ฒ | ๊ฐ์ ๋จธ์ |
| TCP socket | ๋ฐ์ดํฐ | ๋งค๋ฒ | O |
| UDP socket | ๋ฐ์ดํฐ | ๋งค๋ฒ | O |
์์ผ์ IPC ์นดํ๋ก๊ทธ ์ค โ๋งค๋ฒ ์ปค๋ ๊ฒฝ์ + ๋คํธ์ํฌ ๊ฐ๋ฅโ ์๋ฆฌ์ ์์นํ๋ค. ๊ณต์ ๋ฉ๋ชจ๋ฆฌ(๊ฐ์ฅ ๋น ๋ฆ)์ RPC(๊ฐ์ฅ ๋๋ฆผ) ์ฌ์ด์ ์ค๊ฐ ๋น์ฉยท์ค๊ฐ ์ถ์ํยท์ต๊ณ ๋ฒ์ฉ์ฑ.
22๋ฒ ยง12 ๋น์ฉ ํ ์ฌ์ธ์ฉ:
1
2
3
UNIX domain socket send/recv ์ ฮผs
TCP loopback send/recv 5~30 ฮผs
TCP ๋คํธ์ํฌ ์ ms (์ง์ฐ + ๋์ญํญ)
๊ฐ์ ๋จธ์ ์์์ ํ์ดํ์ ๋น์ทํ ๋น์ฉ, ๋คํธ์ํฌ๋ก ๊ฐ๋ฉด ํ ์๋ฆฟ์ ms๋ก ์ฆ๊ฐ. ๊ทธ๋์ โ๊ฐ์ ๋จธ์ + ๋คํธ์ํฌ ๊ฐ๋ฅ์ฑ ๋ชจ๋ ๊ฐ์ง๋คโ ๊ฐ ์์ผ์ ์ง์ง ๊ฐ์น.
1-10. ํํ ํจํด ์ฝ๋
1-10-1. TCP echo server (POSIX)
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
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
int main() {
int sfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(8080),
.sin_addr.s_addr = INADDR_ANY
};
int opt = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sfd, 5);
while (1) {
int cfd = accept(sfd, NULL, NULL);
char buf[1024];
ssize_t n = read(cfd, buf, sizeof(buf));
if (n > 0) write(cfd, buf, n); // echo
close(cfd);
}
close(sfd);
}
1-10-2. UDP receiver
1
2
3
4
5
6
7
8
9
10
11
12
13
int sfd = socket(AF_INET, SOCK_DGRAM, 0); // โ SOCK_DGRAM
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(9000),
.sin_addr.s_addr = INADDR_ANY
};
bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
char buf[1024];
struct sockaddr_in from;
socklen_t fromlen = sizeof(from);
recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
// UDP๋ connect/accept ์์ด recvfrom์ผ๋ก ๋๊ฐ ๋ณด๋๋์ง ๋ฐ์
1-11. ๋ฉด์ ๋ต๋ณ ํ ์ค
โ์์ผ์ ๋คํธ์ํฌ ๋๋ ๊ฐ์ ๋จธ์ ์์์ ๋ endpoint๋ฅผ ์๋ ์๋ฐฉํฅ ํต์ ์ฑ๋์ ์ถ์ํ์ ๋๋ค. OS๊ฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ก ๋ ธ์ถํด ํ์ผ I/O์ ๊ฐ์ API(
read/write)๋ก ๋ค๋ฃฐ ์ ์๊ฒ ํฉ๋๋ค. ์ข ๋ฅ๋ stream(TCP)ยทdatagram(UDP)ยทraw ๋ฑ์ด ์๊ณ , ์ฃผ์ ํจ๋ฐ๋ฆฌ๋ก IPv4(AF_INET)ยทIPv6ยทUNIX domain(AF_UNIX)์ ์ ํํฉ๋๋ค. ๊ฐ์ ๋จธ์ IPC๋ง ํ์ํ๋ฉด UNIX domain์ด TCP loopback๋ณด๋ค 30~50% ๋น ๋ฅด๊ณ ํ์ผ ๊ถํ์ผ๋ก ์ ๊ทผ ์ ์ดํ ์ ์์ด Docker ๋ฐ๋ชฌยทX11ยทsystemd ๊ฐ์ ์์คํ ์๋น์ค์์ ํ์ค์ ๋๋ค. 22๋ฒ์์ ๋ณธ IPC ์นดํ๋ก๊ทธ ์ค โ๋งค๋ฒ ์ปค๋ ๊ฒฝ์ + ๋คํธ์ํฌ ๊ฐ๋ฅโ ์๋ฆฌ์ ์๊ณ , ๊ณต์ ๋ฉ๋ชจ๋ฆฌ(์ ns)์ RPC(์์ญ~์๋ฐฑ ฮผs) ์ฌ์ด์ ์ค๊ฐ ๋น์ฉยท์ต๊ณ ๋ฒ์ฉ์ฑ์ด ์์ผ์ ์๋ฆฌ์ ๋๋ค.โ
ํ๊ท ๋ค๋ฆฌ
22_ipc.mdโ ๋ณธ ๋ฌธ์์ ์๋ณธ ยง10(์์ผ), ยง3(๋ถ๋ฅ์ถ), ยง12(๋น์ฉ ์คํํธ๋ผ)์ด ๋ต๋ณ ๊ทผ๊ฑฐ.21_context_switching.mdโ ๋งค ์ก์์ ๋ง๋ค ๋ฐ์ํ๋ ๋ชจ๋ ์ค์์น ๋น์ฉ์ด ์์ผ ๋น์ฉ์ ์ถ๋ฐ์ .19_process_vs_thread.mdโ ์ฃผ์ ๊ณต๊ฐ ๊ฒฉ๋ฆฌ๊ฐ IPC๊ฐ ํ์ํ ์ด์ ์ ํ ๋.07_pointer_reference.mdโ fd๋ ๊ฒฐ๊ตญ ์ปค๋ ์๋ฃ๊ตฌ์กฐ์ ๋ํ ํธ๋ค(์ถ์ ํฌ์ธํฐ)์ด๋ผ๋ ์ ์์ ๊ฐ์ ์ถ์ํ ํจํด.