์ด ๋ฌธ์์์๋ Unix ์ปค๋์ ํ์ดํ๋ผ์ธ ๊ตฌํ์ ๋ํด ์ค๋ช
ํฉ๋๋ค. "๋ผ๋ ์ ๋ชฉ์ ์ต๊ทผ ๊ธฐ์ฌ์ ๋ค์ ์ค๋งํ์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ๋ฌด์จ ์๋ฆฌํ๋๊ฑฐ์ผ?
ํ์ดํ๋ผ์ธ์ "์๋ง๋ Unix์์ ๊ฐ์ฅ ์ค์ํ ๋ฐ๋ช ํ"์ผ ๊ฒ์ ๋๋ค. ์์ ํ๋ก๊ทธ๋จ๊ณผ ์น์ํ ๋ช ๋ น์ค ์ฌ๋ก๊ฑด์ ๊ฒฐํฉํ๋ Unix์ ๊ธฐ๋ณธ ์ฒ ํ์ ์ ์ํ๋ ํน์ง์ ๋๋ค.
$ echo hello | wc -c
6
์ด ๊ธฐ๋ฅ์ ์ปค๋ ์ ๊ณต ์์คํ
ํธ์ถ์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. pipe
, ์ค๋ช
์ ํ์ด์ง์ ์ค๋ช
๋์ด ์์ต๋๋ค.
ํ์ดํ๋ผ์ธ์ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ์ํ ๋จ๋ฐฉํฅ ์ฑ๋์ ์ ๊ณตํฉ๋๋ค. ํ์ดํ๋ผ์ธ์๋ ์ ๋ ฅ(์ฐ๊ธฐ ๋)๊ณผ ์ถ๋ ฅ(์ฝ๊ธฐ ๋)์ด ์์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ์ ๋ ฅ์ ๊ธฐ๋ก๋ ๋ฐ์ดํฐ๋ ์ถ๋ ฅ์์ โโ์ฝ์ ์ ์์ต๋๋ค.
ํ์ดํ๋ผ์ธ์ ๋ค์์ ํธ์ถํ์ฌ ์์ฑ๋ฉ๋๋ค.
pipe(2)
, ๋ ๊ฐ์ ํ์ผ ์ค๋ช ์๋ฅผ ๋ฐํํฉ๋๋ค. ํ๋๋ ํ์ดํ๋ผ์ธ์ ์ ๋ ฅ์ ๋ํ๋ด๊ณ ๋ ๋ฒ์งธ๋ ์ถ๋ ฅ์ ๋ํ๋ ๋๋ค.
์ ๋ช ๋ น์ ์ถ์ ์ถ๋ ฅ์ ํ์ดํ๋ผ์ธ ์์ฑ๊ณผ ์ด๋ฅผ ํตํด ํ ํ๋ก์ธ์ค์์ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก์ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ณด์ฌ์ค๋๋ค.
$ strace -qf -e execve,pipe,dup2,read,write
sh -c 'echo hello | wc -c'
execve("/bin/sh", ["sh", "-c", "echo hello | wc -c"], โฆ)
pipe([3, 4]) = 0
[pid 2604795] dup2(4, 1) = 1
[pid 2604795] write(1, "hellon", 6) = 6
[pid 2604796] dup2(3, 0) = 0
[pid 2604796] execve("/usr/bin/wc", ["wc", "-c"], โฆ)
[pid 2604796] read(0, "hellon", 16384) = 6
[pid 2604796] write(1, "6n", 2) = 2
์์ ํ๋ก์ธ์ค ํธ์ถ pipe()
์ฒจ๋ถ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ํ๋์ ํ์ ํ๋ก์ธ์ค๋ ํ๋์ ์ค๋ช
์์ ์ฐ๊ณ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ ๋ค๋ฅธ ์ค๋ช
์์์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค. ์์ stdin ๋ฐ stdout๊ณผ ์ผ์นํ๋๋ก dup2๋ก ์ค๋ช
์ 3 ๋ฐ 4๋ฅผ "์ด๋ฆ ๋ณ๊ฒฝ"ํฉ๋๋ค.
ํ์ดํ๋ผ์ธ์ด ์์ผ๋ฉด ์ ธ์ ํ ํ๋ก์ธ์ค์ ์ถ๋ ฅ์ ํ์ผ์ ์ฐ๊ณ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก ํ์ดํํ์ฌ ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ผ ํฉ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ ๋ง์ ๋ฆฌ์์ค์ ๋์คํฌ ๊ณต๊ฐ์ ๋ญ๋นํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ํ์ดํ๋ผ์ธ์ ์์ ํ์ผ์ ํผํ๋ ๊ฒ ์ด์์ผ๋ก ์ ์ฉํฉ๋๋ค.
ํ๋ก์ธ์ค๊ฐ ๋น ํ์ดํ๋ผ์ธ์์ ์ฝ์ผ๋ ค๊ณ ํ๋ฉด
read(2)
๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ ๋๊น์ง ์ฐจ๋จ๋ฉ๋๋ค. ํ๋ก์ธ์ค๊ฐ ์ ์ฒด ํ์ดํ๋ผ์ธ์ ์ฐ๊ธฐ๋ฅผ ์๋ํ๋ฉดwrite(2)
์ฐ๊ธฐ๋ฅผ ์๋ฃํ๊ธฐ ์ํด ํ์ดํ๋ผ์ธ์์ ์ถฉ๋ถํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ๋๊น์ง ์ฐจ๋จ๋ฉ๋๋ค.
POSIX ์๊ตฌ ์ฌํญ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ด๊ฒ์ ์ค์ํ ์์ฑ์
๋๋ค. PIPE_BUF
๋ฐ์ดํธ(์ต์ 512)๋ ์ผ๋ฐ ํ์ผ(๊ทธ๋ฌํ ๋ณด์ฅ์ ์ ๊ณตํ์ง ์์)์ด ํ ์ ์๋ ๋ฐฉ์์ผ๋ก ํ๋ก์ธ์ค๊ฐ ํ์ดํ๋ผ์ธ์ ํตํด ์๋ก ํต์ ํ ์ ์๋๋ก ์์์ ์ด์ด์ผ ํฉ๋๋ค.
์ผ๋ฐ ํ์ผ์ ์ฌ์ฉํ๋ฉด ํ๋ก์ธ์ค๋ ๋ชจ๋ ์ถ๋ ฅ์ ์ฌ๊ธฐ์ ์ฐ๊ณ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก ์ ๋ฌํ ์ ์์ต๋๋ค. ๋๋ ํ๋ก์ธ์ค๋ ์ธ๋ถ ์ ํธ ๋ฉ์ปค๋์ฆ(์: ์ธ๋งํฌ์ด)์ ์ฌ์ฉํ์ฌ ํ๋ ๋ณ๋ ฌ ๋ชจ๋์์ ์๋ํ์ฌ ์ฐ๊ธฐ ๋๋ ์ฝ๊ธฐ ์๋ฃ์ ๋ํด ์๋ก์๊ฒ ์๋ฆด ์ ์์ต๋๋ค. ์ปจ๋ฒ ์ด์ด๋ ์ด ๋ชจ๋ ๋ฒ๊ฑฐ๋ก์์์ ์ฐ๋ฆฌ๋ฅผ ๊ตฌํด์ค๋๋ค.
์ฐ๋ฆฌ๋ ๋ฌด์์ ์ฐพ๊ณ ์์ต๋๊น?
์ปจ๋ฒ ์ด์ด๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง ์ฝ๊ฒ ์์ํ ์ ์๋๋ก ์๊ฐ๋ฝ์ผ๋ก ์ค๋ช ํ๊ฒ ์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ์ ๋ฒํผ์ ์ผ๋ถ ์ํ๋ฅผ ํ ๋นํด์ผ ํฉ๋๋ค. ๋ฒํผ์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์ ๊ฑฐํ๋ ๊ธฐ๋ฅ์ด ํ์ํฉ๋๋ค. ํ์ผ ์ค๋ช ์์ ๋ํ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์์ ์ค์ ํจ์๋ฅผ ํธ์ถํ๋ ค๋ฉด ์ผ๋ถ ๊ธฐ๋ฅ์ด ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์์ ์ค๋ช ํ ํน์ ๋์์ ๊ตฌํํ๋ ค๋ฉด ์ ๊ธ์ด ํ์ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ด์ ๋ง์ฐํ ์ ์ ๋ชจ๋ธ์ ํ์ธํ๊ฑฐ๋ ๋ฐ์ฆํ๊ธฐ ์ํด ๋ฐ์ ๋จํ ์๋์์ ์ปค๋์ ์์ค ์ฝ๋๋ฅผ ์กฐ์ฌํ ์ค๋น๊ฐ ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ํญ์ ์์์น ๋ชปํ ์ํฉ์ ๋๋นํ์ญ์์ค.
์ฐ๋ฆฌ๋ ์ด๋๋ฅผ ์ฐพ๊ณ ์์ต๋๊น?
๋๋ ๊ทธ ์ ๋ช
ํ ์ฑ
์ ์ฌ๋ณธ์ด ์ด๋์ ์๋์ง ๋ชจ๋ฅธ๋ค.
TUHS ์์นด์ด๋ธ๋ฅผ ๋์๋ค๋๋ ๊ฒ์ ๋ฐ๋ฌผ๊ด์ ๋ฐฉ๋ฌธํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ฐ๋ฆฌ์ ๊ณต์ ๋ ์ญ์ฌ๋ฅผ ๋ณผ ์ ์์ผ๋ฉฐ ์ค๋๋ ์นด์ธํธ์ ์ถ๋ ฅ๋ฌผ์์ ์ด ๋ชจ๋ ์๋ฃ๋ฅผ ์กฐ๊ธ์ฉ ๋ณต๊ตฌํ๋ ค๋ ์๋ ๊ฐ์ ๋ ธ๋ ฅ์ ๊ฒฝ์๋ฅผ ํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ์์ง ์์ด๋ฒ๋ฆฐ ์กฐ๊ฐ๋ค์ ์ ์คํ ์๊ณ ์์ต๋๋ค.
ํ์ดํ๋ผ์ธ์ ๊ณ ๋ ์ญ์ฌ์ ๋ํ ํธ๊ธฐ์ฌ์ ๋ง์กฑ์ํค๋ฉด ๋น๊ต๋ฅผ ์ํด ํ๋ ์ฝ์ด๋ฅผ ์ดํด๋ณผ ์ ์์ต๋๋ค.
๋ํ, pipe
ํ
์ด๋ธ์์ ์์คํ
ํธ์ถ ๋ฒํธ 42์
๋๋ค. sysent[]
. ์ฐ์ฐ์ ์ผ์น?
์ ํต์ ์ธ ์ ๋์ค ์ปค๋(1970โ1974)
์๋ฌด ํ์ ๋ ๋ชป ์ฐพ์์ด pipe(2)
์ด๋ ์ชฝ๋
TUHS๋
Unix์ ์ธ ๋ฒ์งธ ์๋์ ์ ์ปค๋์ด ์ด์ ๋ธ๋ฌ๋ก ์์ฑ๋ ๋ง์ง๋ง ๋ฒ์ ์ด์ ํ์ดํ๋ผ์ธ์ด ์๋ ์ฒซ ๋ฒ์งธ ๋ฒ์ ์ด๊ธฐ๋ ํฉ๋๋ค. 1973๋ ์ ์ XNUMXํ์ ๊ฐ์ ํ๊ธฐ ์ํ ์์ ์ด ์งํ ์ค์ด์๊ณ ์ปค๋์ C๋ก ์ฌ์์ฑ๋์ด ์ ๋์ค ์ XNUMXํ์ด ํ์ํ์ต๋๋ค.
ํ ๋ ์๋ Doug McIlroy๊ฐ "์ ์ ํธ์ค์ ๊ฐ์ ์ฐ๊ฒฐ ํ๋ก๊ทธ๋จ"์ด๋ผ๋ ์์ด๋์ด๋ฅผ ์ ์ํ ๋ฌธ์ ์ค์บ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
๋ธ๋ผ์ด์ธ ์ปค๋๊ฑด์ ์ฑ
์์
Unix๊ฐ ๋ฑ์ฅํ์ ๋ ์ฝ๋ฃจํด์ ๋ํ ๋์ ์ด์ ์ OS ์์ฑ์์ธ Ken Thompson์๊ฒ ์ผ๋ถ ํ๋ก์ธ์ค์ ๊ธฐ๋ก๋ ๋ฐ์ดํฐ๊ฐ ์ฅ์น๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก์ ์ข ๋ฃ์๋ ํ์ฉ๋๋๋ก ์์ฒญํ์ต๋๋ค. Ken์ ๊ทธ๊ฒ์ด ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฏธ๋๋ฉ๋ฆฌ์คํธ๋ก์ ๊ทธ๋ ๋ชจ๋ ์์คํ ๊ธฐ๋ฅ์ด ์ค์ํ ์ญํ ์ ํ๊ธฐ๋ฅผ ์ํ์ต๋๋ค. ์ค๊ฐ ํ์ผ์ ์ฐ๋ ๊ฒ๋ณด๋ค ํ๋ก์ธ์ค ๊ฐ ์ง์ ์ฐ๊ธฐ๊ฐ ์ค์ ๋ก ํฐ ์ด์ ์ ๋๊น? ๊ทธ๋ฆฌ๊ณ "ํ์ดํ๋ผ์ธ"์ด๋ผ๋ ๋์ ๋๋ ์ด๋ฆ๊ณผ ํ๋ก์ธ์ค ์ํธ ์์ฉ ๊ตฌ๋ฌธ์ ๋ํ ์ค๋ช ์ผ๋ก ํน์ ์ ์์ํ์ ๋๋ง Ken์ ๋ง์นจ๋ด "๋ด๊ฐ ํ ๊ฒ์ ๋๋ค! "๋ผ๊ณ ์ธ์ณค์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฌ๋ค. ์ด๋ ์ด๋ช ์ ์ธ ์ ๋ ์ Ken์ ์ปค๋๊ณผ ์ ธ์ ๋ณ๊ฒฝํ๊ณ ์ฌ๋ฌ ํ์ค ํ๋ก๊ทธ๋จ์ ์์ ํ์ฌ ์ ๋ ฅ(ํ์ดํ๋ผ์ธ์์ ์ฌ ์ ์์)์ ๋ฐ์๋ค์ด๋ ๋ฐฉ๋ฒ์ ํ์คํํ๊ณ ํ์ผ ์ด๋ฆ์ ๋ณ๊ฒฝํ์ต๋๋ค. ๋ค์๋ ํ์ดํ๋ผ์ธ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋งค์ฐ ๋๋ฆฌ ์ฌ์ฉ๋์์ต๋๋ค. ์ฃผ๋ง๊น์ง ๋น์๋ค์ ๋ฌธ์๋ฅผ ์๋ ํ๋ก์ธ์์์ ํ๋ฆฐํฐ๋ก ๋ณด๋ด๋ ๋ฐ ์ฌ์ฉํ์ต๋๋ค. ์ผ๋ง ํ Ken์ ํ์ดํ๋ผ์ธ ์ฌ์ฉ์ ๋ฉํํ๊ธฐ ์ํ ์๋ API์ ๊ตฌ๋ฌธ์ ๊ทธ ์ดํ๋ก ์ฌ์ฉ๋ ๋ ๊น๋ํ ๊ท์น์ผ๋ก ๊ต์ฒดํ์ต๋๋ค.
๋ถํํ๊ฒ๋ ์ XNUMXํ ์ ๋์ค ์ปค๋์ ์์ค ์ฝ๋๋ ์ ์ค๋์์ต๋๋ค. C๋ก ์์ฑ๋ ์ปค๋ ์์ค ์ฝ๋๊ฐ ์์ง๋ง
๋ค์์ ๋ํ ๋ฌธ์ ํ
์คํธ๊ฐ ์์ต๋๋ค. pipe(2)
๋ ๋ฆด๋ฆฌ์ค ๋ชจ๋์์ ๋ฌธ์๋ฅผ ๊ฒ์ํ์ฌ ์์ํ ์ ์์ต๋๋ค. pipe(2)
์ด์
๋ธ๋ฌ๋ก ์์ฑ๋์์ผ๋ฉฐ ํ๋์ ํ์ผ ์ค๋ช
์๋ง ๋ฐํํ์ง๋ง ์ด๋ฏธ ์์๋๋ ํต์ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์์คํ ํธ์ถ ํ์ดํ ํ์ดํ๋ผ์ธ์ด๋ผ๋ I/O ๋ฉ์ปค๋์ฆ์ ์์ฑํฉ๋๋ค. ๋ฐํ๋ ํ์ผ ์ค๋ช ์๋ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ฐ๋ฉด ์ต๋ 504๋ฐ์ดํธ์ ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ๋งํ ํ ์ฐ๊ธฐ ํ๋ก์ธ์ค๊ฐ ์ผ์ ์ค๋จ๋ฉ๋๋ค. ํ์ดํ๋ผ์ธ์์ ์ฝ์ ๋ ๋ฒํผ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
์ด๋ฌํด ์ปค๋์ C๋ก ์ฌ์์ฑ๋์๊ณ , pipe(fildes)
ยป:
์์คํ ํธ์ถ ํ์ดํ ํ์ดํ๋ผ์ธ์ด๋ผ๋ I/O ๋ฉ์ปค๋์ฆ์ ์์ฑํฉ๋๋ค. ๋ฐํ๋ ํ์ผ ์ค๋ช ์๋ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฌด์ธ๊ฐ๊ฐ ํ์ดํ๋ผ์ธ์ ๊ธฐ๋ก๋๋ฉด r1(resp. fildes[1])์ ๋ฐํ๋ ์ค๋ช ์๊ฐ ์ฌ์ฉ๋๋ฉฐ ์ต๋ 4096๋ฐ์ดํธ์ ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ๋งํ ํ ์ฐ๊ธฐ ํ๋ก์ธ์ค๊ฐ ์ผ์ ์ค๋จ๋ฉ๋๋ค. ํ์ดํ๋ผ์ธ์์ ์ฝ์ ๋ r0์ผ๋ก ๋ฐํ๋ ์ค๋ช ์(๊ฐ๊ฐ fildes[0])๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
์ผ๋จ ํ์ดํ๋ผ์ธ์ด ์ ์๋๋ฉด ๋ ๊ฐ(๋๋ ๊ทธ ์ด์)์ ์ํธ ์์ฉ ํ๋ก์ธ์ค(ํ์ ํธ์ถ์ ์ํด ์์ฑ๋จ)๊ฐ ํฌํฌ) ํธ์ถ์ ์ฌ์ฉํ์ฌ ํ์ดํ๋ผ์ธ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค. ์ฝ๊ธฐ ะธ ์ฐ๋ค.
์ ธ์๋ ํ์ดํ๋ผ์ธ์ ํตํด ์ฐ๊ฒฐ๋ ํ๋ก์ธ์ค์ ์ ํ ๋ฐฐ์ด์ ์ ์ํ๊ธฐ ์ํ ๊ตฌ๋ฌธ์ด ์์ต๋๋ค.
ํ์ชฝ ๋๋ง ์๋(๋ชจ๋ ์ฐ๊ธฐ ํ์ผ ์ค๋ช ์๊ฐ ๋ซํ) ๋น์ด ์๋ ํ์ดํ๋ผ์ธ(๋ฒํผ๋ง๋ ๋ฐ์ดํฐ ํฌํจ)์์ ์ฝ๊ธฐ ํธ์ถ์ "ํ์ผ ๋"์ ๋ฐํํฉ๋๋ค. ์ ์ฌํ ์ํฉ์ ์ฐ๊ธฐ ํธ์ถ์ ๋ฌด์๋ฉ๋๋ค.
๊ฐ์ฅ ์ด๋ฅธ
์ ๋์ค 1975ํ(XNUMX)
Unix ์์ค ์ฝ๋ ์ฝ๊ธฐ ์์
์๋ ๋์ ์ฑ ์ฌ์ Bell Labs ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋ Unix ์ปค๋์ ๋ํ ์ ์ผํ ๋ฌธ์์์ต๋๋ค. XNUMXํ ๋ผ์ด์ ์ค์์๋ ๊ต์ฌ๊ฐ ์์ค ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ์ฉํ์ง๋ง XNUMXํ ๋ผ์ด์ ์ค์์๋ ์ด๋ฌํ ๊ฐ๋ฅ์ฑ์ ๋ฐฐ์ ํ์ฌ ๋ถ๋ฒ ํ์๋ณธ์ผ๋ก ๋ฐฐํฌ๋์์ต๋๋ค.
์ค๋ ๋ณต์ฌ๊ธฐ์์ ํ์๋ค์ ๋ฌ์ฌํ๋ ์ฑ
์ ์ฌ ์ธ์ ์ฌ๋ณธ์ ๊ตฌ์
ํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ TUHS ํ๋ก์ ํธ๋ฅผ ์์ํ Warren Toomey ๋๋ถ์
15๋ ์ ์ ์ ๋ ์ฌ์์๋ ค์ง์ง ์์ ๋ค๋ฅธ ์ฌ๋ณธ์ ํ์ง์ด ๋ง์์ ๋ค์ง ์์๊ธฐ ๋๋ฌธ์ ๋๋ค. TUHS๋ ์์ง ์กด์ฌํ์ง ์์๊ณ ์ด์ ์์ค์ ์ก์ธ์คํ ์ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ 1988๋ ์ PDP9 ์ปดํจํฐ์์ ๋ฐฑ์ ํ 11๊ฐ ํธ๋์ด ์๋ ์ค๋๋ ํ ์ดํ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ์๋ ์ฌ๋ถ๋ฅผ ์๊ธฐ๋ ์ด๋ ค์ ์ง๋ง ๋๋ถ๋ถ์ ํ์ผ์ด 1979๋ ์ผ๋ก ํ์๋์ด ์๋ ์จ์ ํ /usr/src/ ํธ๋ฆฌ๊ฐ ์์๋๋ฐ ๋น์์๋ ์ค๋๋ ๊ฒ์ผ๋ก ๋ณด์์ต๋๋ค. ์ผ๊ณฑ ๋ฒ์งธ ํ ๋๋ PWB ํ์๋ฌผ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
๋๋ ๋ฐ๊ฒฌ์ ๊ธฐ์ด๋ก ์ผ์ ์ถ์ฒ๋ฅผ ์ฌ์ฏ ๋ฒ์งธ ํ์ ์ํ๋ก ์๋์ผ๋ก ํธ์งํ์ต๋๋ค. ์ฝ๋์ ์ผ๋ถ๋ ๋์ผํ๊ฒ ์ ์ง๋์๊ณ ์ผ๋ถ๋ ์ฝ๊ฐ ํธ์งํ์ฌ ์ต์ ํ ํฐ +=์ ๊ตฌ์ =+๋ก ๋ณ๊ฒฝํด์ผ ํ์ต๋๋ค. ์ด๋ค ๊ฒ์ ๋จ์ํ ์ญ์ ๋์๊ณ ์ด๋ค ๊ฒ์ ์์ ํ ๋ค์ ์์ฑ๋์ด์ผ ํ์ง๋ง ๋๋ฌด ๋ง์ง๋ ์์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ค๋ ์ฐ๋ฆฌ๋ TUHS์์ XNUMXํ์ ์์ค ์ฝ๋๋ฅผ ์จ๋ผ์ธ์ผ๋ก ์ฝ์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ธ๋ป ๋ณด๊ธฐ์ ์ปค๋๊ฑด๊ณผ ๋ฆฌ์น ์๋ ์ด์ ์ C ์ฝ๋์ ์ฃผ์ ํน์ง์ ๊ฐ๊ฒฐ. ๋ด ์ฌ์ดํธ์ ์๋์ ์ผ๋ก ์ข์ ํ์ ์์ญ์ ๋ง๊ฒ ๊ด๋ฒ์ํ ํธ์ง ์์ด ์ฝ๋ ์ค๋ํซ์ ์ฝ์ ํ ์ ์๋ ๊ฒฝ์ฐ๋ ๋๋ญ ๋๋ค.
์ด๊ธฐ์
/*
* Max allowable buffering per pipe.
* This is also the max size of the
* file created to implement the pipe.
* If this size is bigger than 4096,
* pipes will be implemented in LARG
* files, which is probably not good.
*/
#define PIPSIZ 4096
๋ฒํผ ํฌ๊ธฐ๋ XNUMXํ ์ดํ๋ก ๋ณ๊ฒฝ๋์ง ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๊ธฐ์์๋ ๊ณต๊ฐ ๋ฌธ์ ์์ด ํ์ดํ๋ผ์ธ์ด ํ๋ ํ์ผ์ ๋์ฒด ์คํ ๋ฆฌ์ง๋ก ์ฌ์ฉํ์์ ์ ์ ์์ต๋๋ค!
LARG ํ์ผ์ ๋ค์์ ํด๋นํฉ๋๋ค.
๋ค์์ ์ค์ ์์คํ
ํธ์ถ์
๋๋ค. pipe
:
/*
* The sys-pipe entry.
* Allocate an inode on the root device.
* Allocate 2 file structures.
* Put it all together with flags.
*/
pipe()
{
register *ip, *rf, *wf;
int r;
ip = ialloc(rootdev);
if(ip == NULL)
return;
rf = falloc();
if(rf == NULL) {
iput(ip);
return;
}
r = u.u_ar0[R0];
wf = falloc();
if(wf == NULL) {
rf->f_count = 0;
u.u_ofile[r] = NULL;
iput(ip);
return;
}
u.u_ar0[R1] = u.u_ar0[R0]; /* wf's fd */
u.u_ar0[R0] = r; /* rf's fd */
wf->f_flag = FWRITE|FPIPE;
wf->f_inode = ip;
rf->f_flag = FREAD|FPIPE;
rf->f_inode = ip;
ip->i_count = 2;
ip->i_flag = IACC|IUPD;
ip->i_mode = IALLOC;
}
์ฃผ์์ ์ฌ๊ธฐ์ ์ผ์ด๋๋ ์ผ์ ๋ช
ํํ๊ฒ ์ค๋ช
ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ถ๋ถ์ ์ผ๋ก "R0
ะธ R1
์์คํ
ํธ์ถ ๋งค๊ฐ ๋ณ์์ ๋ฐํ ๊ฐ์ด ์ ๋ฌ๋ฉ๋๋ค.
ํจ๊ป ํด๋ณด์
pipe()
๊ธฐํ R0
ะธ R1
์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ๋ฅผ ์ํ ํ์ผ ์ค๋ช
์ ๋ฒํธ๋ฅผ ๋ฐํํฉ๋๋ค. falloc()
ํ์ผ ๊ตฌ์กฐ์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ์ง๋ง ๋ค์์ ํตํด "๋ฐํ"ํ๊ธฐ๋ ํฉ๋๋ค. u.u_ar0[R0]
๋ฐ ํ์ผ ์ค๋ช
์. ์ฆ, ์ฝ๋๋ ๋ค์ ์์น์ ์ ์ฅ๋ฉ๋๋ค. r
์ฝ๊ธฐ๋ฅผ ์ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ์์ ์ง์ ์ฐ๊ธฐ๋ฅผ ์ํ ๋์คํฌ๋ฆฝํฐ๋ฅผ ํ ๋นํฉ๋๋ค. u.u_ar0[R0]
๋ ๋ฒ์งธ ํตํ ํ falloc()
.
๊น๋ฐ FPIPE
ํ์ดํ๋ผ์ธ์ ๋ง๋ค ๋ ์ค์ ํ ๋ ํจ์์ ๋์์ ์ ์ดํฉ๋๋ค.
/*
* common code for read and write calls:
* check permissions, set base, count, and offset,
* and switch out to readi, writei, or pipe code.
*/
rdwr(mode)
{
register *fp, m;
m = mode;
fp = getf(u.u_ar0[R0]);
/* โฆ */
if(fp->f_flag&FPIPE) {
if(m==FREAD)
readp(fp); else
writep(fp);
}
/* โฆ */
}
๊ทธ๋ฐ ๋ค์ ๊ธฐ๋ฅ readp()
ะฒ pipe.c
ํ์ดํ๋ผ์ธ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค์๋ถํฐ ์์ํ์ฌ ๊ตฌํ์ ์ถ์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. writep()
. ๋ค์ ๋งํ์ง๋ง ์ธ์ ์ ๋ฌ ๊ท์น์ ํน์ฑ์ผ๋ก ์ธํด ์ฝ๋๊ฐ ๋ ๋ณต์กํด์ก์ง๋ง ์ผ๋ถ ์ธ๋ถ ์ ๋ณด๋ ์๋ต๋ ์ ์์ต๋๋ค.
writep(fp)
{
register *rp, *ip, c;
rp = fp;
ip = rp->f_inode;
c = u.u_count;
loop:
/* If all done, return. */
plock(ip);
if(c == 0) {
prele(ip);
u.u_count = 0;
return;
}
/*
* If there are not both read and write sides of the
* pipe active, return error and signal too.
*/
if(ip->i_count < 2) {
prele(ip);
u.u_error = EPIPE;
psignal(u.u_procp, SIGPIPE);
return;
}
/*
* If the pipe is full, wait for reads to deplete
* and truncate it.
*/
if(ip->i_size1 == PIPSIZ) {
ip->i_mode =| IWRITE;
prele(ip);
sleep(ip+1, PPIPE);
goto loop;
}
/* Write what is possible and loop back. */
u.u_offset[0] = 0;
u.u_offset[1] = ip->i_size1;
u.u_count = min(c, PIPSIZ-u.u_offset[1]);
c =- u.u_count;
writei(ip);
prele(ip);
if(ip->i_mode&IREAD) {
ip->i_mode =& ~IREAD;
wakeup(ip+2);
}
goto loop;
}
ํ์ดํ๋ผ์ธ ์
๋ ฅ์ ๋ฐ์ดํธ๋ฅผ ์ฐ๊ณ ์ถ์ต๋๋ค. u.u_count
. ๋จผ์ inode๋ฅผ ์ ๊ธ ํ์๊ฐ ์์ต๋๋ค(์๋ ์ฐธ์กฐ). plock
/prele
).
๊ทธ๋ฐ ๋ค์ inode ์ฐธ์กฐ ํ์๋ฅผ ํ์ธํฉ๋๋ค. ํ์ดํ๋ผ์ธ์ ์์ชฝ ๋์ด ์ด๋ ค ์๋ ํ ์นด์ดํฐ๋ 2์ฌ์ผ ํฉ๋๋ค. rp->f_inode
), ๋ฐ๋ผ์ ์นด์ดํฐ๊ฐ 2 ๋ฏธ๋ง์ด๋ฉด ์ฝ๊ธฐ ํ๋ก์ธ์ค๊ฐ ํ์ดํ๋ผ์ธ์ ๋์ ๋ซ์๋ค๋ ์๋ฏธ์
๋๋ค. ์ฆ, ๋ซํ ํ์ดํ๋ผ์ธ์ ์ฐ๊ธฐ๋ฅผ ์๋ํ๊ณ ์๋๋ฐ ์ด๋ ์ค์์
๋๋ค. ์ฒซ ๋ฒ์งธ ์ค๋ฅ ์ฝ๋ EPIPE
๊ทธ๋ฆฌ๊ณ ์ ํธ SIGPIPE
์ ๋์ค XNUMXํ์์ ๋ฑ์ฅ.
๊ทธ๋ฌ๋ ์ปจ๋ฒ ์ด์ด๊ฐ ์ด๋ ค ์์ด๋ ๊ฐ๋ ์ฐฐ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ํ์ดํ๋ผ์ธ์์ ์ฝ๊ณ ์ถฉ๋ถํ ๊ณต๊ฐ์ ํ๋ณดํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ ์ ๊ธ์ ํด์ ํ๊ณ ์ ์ ๋ชจ๋๋ก ์ ํํฉ๋๋ค. ๊นจ์ด๋๋ฉด ์ฒ์์ผ๋ก ๋์๊ฐ์ ๋ค์ ์ ๊ธ์ ํด์ ํ๊ณ ์๋ก์ด ์ฐ๊ธฐ ์ฃผ๊ธฐ๋ฅผ ์์ํฉ๋๋ค.
ํ์ดํ๋ผ์ธ์ ์ถฉ๋ถํ ์ฌ์ ๊ณต๊ฐ์ด ์์ผ๋ฉด ๋ค์์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์๋๋ค. i_size1
inode'a(๋น ํ์ดํ๋ผ์ธ์ด 0์ผ ์ ์์)๋ ์ด๋ฏธ ํฌํจ๋ ๋ฐ์ดํฐ์ ๋์ ๊ฐ๋ฆฌํต๋๋ค. ์ธ ๊ณต๊ฐ์ด ์ถฉ๋ถํ๋ฉด ํ์ดํ๋ผ์ธ์ ์ฑ์ธ ์ ์์ต๋๋ค. i_size1
์ PIPESIZ
. ๊ทธ๋ฐ ๋ค์ ์ ๊ธ์ ํด์ ํ๊ณ ํ์ดํ๋ผ์ธ์์ ์ฝ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์ฐ๋ ค๊ณ ํฉ๋๋ค. ์ฒ์์ผ๋ก ๋์๊ฐ์ ํ์ํ ๋งํผ์ ๋ฐ์ดํธ๋ฅผ ์ธ ์ ์์๋์ง ํ์ธํฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ ๊ธฐ๋ก ์ฃผ๊ธฐ๋ฅผ ์์ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋งค๊ฐ๋ณ์ i_mode
inode๋ ๊ถํ์ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. r
, w
ะธ x
. ๊ทธ๋ฌ๋ ํ์ดํ๋ผ์ธ์ ๊ฒฝ์ฐ ๋นํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ผ๋ถ ํ๋ก์ธ์ค๊ฐ ์ฐ๊ธฐ ๋๋ ์ฝ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์์ ์๋ฆฝ๋๋ค. IREAD
ะธ IWRITE
๊ฐ๊ธฐ. ํ๋ก์ธ์ค๋ ํ๋๊ทธ๋ฅผ ์ค์ ํ๊ณ ํธ์ถํฉ๋๋ค. sleep()
, ๊ทธ๋ฆฌ๊ณ ๋ฏธ๋์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ํธ์ถํ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค. wakeup()
.
์ง์ ํ ๋ง๋ฒ์ sleep()
ะธ wakeup()
. ๊ทธ๋ค์์์ ๊ตฌํ๋ฉ๋๋ค
/*
* Give up the processor till a wakeup occurs
* on chan, at which time the process
* enters the scheduling queue at priority pri.
* The most important effect of pri is that when
* pri<0 a signal cannot disturb the sleep;
* if pri>=0 signals will be processed.
* Callers of this routine must be prepared for
* premature return, and check that the reason for
* sleeping has gone away.
*/
sleep(chan, pri) /* โฆ */
/*
* Wake up all processes sleeping on chan.
*/
wakeup(chan) /* โฆ */
ํธ์ถํ๋ ํ๋ก์ธ์ค sleep()
ํน์ ์ฑ๋์ ๊ฒฝ์ฐ ๋์ค์ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ํด ๊นจ์ด๋ ์ ์์ต๋๋ค. wakeup()
๋์ผํ ์ฑ๋์ ๋ํด. writep()
ะธ readp()
์ด๋ฌํ ํ์ด๋ง ํตํ๋ฅผ ํตํด ์์
์ ์กฐ์ ํฉ๋๋ค. ์ฐธ๊ณ pipe.c
ํญ์ ์ฐ์ ์์ PPIPE
๋ถ๋ฅผ ๋ sleep()
, ๊ทธ๋์ ๋ชจ๋ sleep()
์ ํธ์ ์ํด ์ค๋จ๋ ์ ์์ต๋๋ค.
์ด์ ๊ธฐ๋ฅ์ ์ดํดํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ด ์์ต๋๋ค. readp()
:
readp(fp)
int *fp;
{
register *rp, *ip;
rp = fp;
ip = rp->f_inode;
loop:
/* Very conservative locking. */
plock(ip);
/*
* If the head (read) has caught up with
* the tail (write), reset both to 0.
*/
if(rp->f_offset[1] == ip->i_size1) {
if(rp->f_offset[1] != 0) {
rp->f_offset[1] = 0;
ip->i_size1 = 0;
if(ip->i_mode&IWRITE) {
ip->i_mode =& ~IWRITE;
wakeup(ip+1);
}
}
/*
* If there are not both reader and
* writer active, return without
* satisfying read.
*/
prele(ip);
if(ip->i_count < 2)
return;
ip->i_mode =| IREAD;
sleep(ip+2, PPIPE);
goto loop;
}
/* Read and return */
u.u_offset[0] = 0;
u.u_offset[1] = rp->f_offset[1];
readi(ip);
rp->f_offset[1] = u.u_offset[1];
prele(ip);
}
์ด ํจ์๋ฅผ ์๋์์ ์๋ก ์ฝ๋ ๊ฒ์ด ๋ ์ฌ์ธ ์ ์์ต๋๋ค. "์ฝ๊ณ ๋ฐํ" ๋ถ๊ธฐ๋ ์ผ๋ฐ์ ์ผ๋ก ํ์ดํ๋ผ์ธ์ ์ผ๋ถ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ์ฐ๋ฆฌ๋ f_offset
์ฝ์ ๋ค์ ํด๋น ์คํ์
๊ฐ์ ์
๋ฐ์ดํธํฉ๋๋ค.
ํ์ ์ฝ๊ธฐ์์ ์ฝ๊ธฐ ์คํ์
์ ๋๋ฌํ๋ฉด ํ์ดํ๋ผ์ธ์ด ๋น์ด ์๊ฒ ๋ฉ๋๋ค. i_size1
์์ด๋
ธ๋์์. ์์น๋ฅผ 0์ผ๋ก ์ฌ์ค์ ํ๊ณ ํ์ดํ๋ผ์ธ์ ์ฐ๊ธฐ๋ฅผ ์ํ๋ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์ฐ๋ ค๊ณ ํฉ๋๋ค. ์ปจ๋ฒ ์ด์ด๊ฐ ๊ฐ๋ ์ฐจ๋ฉด writep()
์ ์ ๋ค๋ค ip+1
. ์ด์ ํ์ดํ๋ผ์ธ์ด ๋น์ด ์์ผ๋ฏ๋ก ์ ์ ๋ชจ๋๋ฅผ ํด์ ํ์ฌ ์ฐ๊ธฐ ์ฃผ๊ธฐ๋ฅผ ์ฌ๊ฐํ ์ ์์ต๋๋ค.
์ฝ์ ๊ฒ์ด ์๋ค๋ฉด, readp()
ํ๋๊ทธ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค IREAD
๊ทธ๋ฆฌ๊ณ ์ ๋ค๋ค ip+2
. ์ฐ๋ฆฌ๋ ๋ฌด์์ด ๊ทธ๋ฅผ ๊นจ์ธ์ง ์๋๋ค writep()
ํ์ดํ๋ผ์ธ์ ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ธ ๋.
์ ๋ํ ๋๊ธ u
ยป ํ์ผ, ์์น, ๋ฉ๋ชจ๋ฆฌ์ ๋ฒํผ๋ฅผ ์ทจํ๊ณ ์ฝ๊ฑฐ๋ ์ธ ๋ฐ์ดํธ ์๋ฅผ ๊ณ์ฐํ๋ ์ผ๋ฐ I/O ํจ์์ฒ๋ผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
/*
* Read the file corresponding to
* the inode pointed at by the argument.
* The actual read arguments are found
* in the variables:
* u_base core address for destination
* u_offset byte offset in file
* u_count number of bytes to read
* u_segflg read to kernel/user
*/
readi(aip)
struct inode *aip;
/* โฆ */
/*
* Write the file corresponding to
* the inode pointed at by the argument.
* The actual write arguments are found
* in the variables:
* u_base core address for source
* u_offset byte offset in file
* u_count number of bytes to write
* u_segflg write to kernel/user
*/
writei(aip)
struct inode *aip;
/* โฆ */
"๋ณด์์ " ์ฐจ๋จ์ ๊ดํด์๋ readp()
ะธ writep()
์๋ฃ๋๊ฑฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ๋๊น์ง inode๋ฅผ ์ ๊ธ๋๋ค(์: wakeup
). plock()
ะธ prele()
๊ฐ๋จํ๊ฒ ์์
: ๋ค๋ฅธ ํธ์ถ ์ธํธ ์ฌ์ฉ sleep
ะธ wakeup
๋ฐฉ๊ธ ํด์ ํ ์ ๊ธ์ด ํ์ํ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์ธ ์ ์์ต๋๋ค.
/*
* Lock a pipe.
* If its already locked, set the WANT bit and sleep.
*/
plock(ip)
int *ip;
{
register *rp;
rp = ip;
while(rp->i_flag&ILOCK) {
rp->i_flag =| IWANT;
sleep(rp, PPIPE);
}
rp->i_flag =| ILOCK;
}
/*
* Unlock a pipe.
* If WANT bit is on, wakeup.
* This routine is also used to unlock inodes in general.
*/
prele(ip)
int *ip;
{
register *rp;
rp = ip;
rp->i_flag =& ~ILOCK;
if(rp->i_flag&IWANT) {
rp->i_flag =& ~IWANT;
wakeup(rp);
}
}
์ฒ์์๋ ์ ๊ทธ๋ฐ์ง ์ดํดํ ์ ์์์ต๋๋ค. readp()
๋ฐ์ํ์ง ์์ต๋๋ค prele(ip)
์ ํํ๊ธฐ ์ ์ wakeup(ip+1)
. ์ฒซ ๋ฒ์งธ writep()
๋ฃจํ์์ ํธ์ถํฉ๋๋ค. plock(ip)
, ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๊ต์ฐฉ ์ํ๊ฐ ๋ฐ์ํฉ๋๋ค. readp()
์์ง ๋ธ๋ก์ ์ ๊ฑฐํ์ง ์์์ผ๋ฏ๋ก ์ฝ๋๊ฐ ์ด๋ป๊ฒ๋ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํด์ผ ํฉ๋๋ค. ๋ณด๋ฉด wakeup()
, ์ด๋ ํด๋ฉด ํ๋ก์ธ์ค๋ฅผ ์คํํ ์ค๋น๊ฐ ๋ ๊ฒ์ผ๋ก๋ง ํ์ํ๋ฏ๋ก ๋ฏธ๋์ sched()
์ ๋ง ๊ฐ์ํ์ต๋๋ค. ๊ทธ๋์ readp()
์์ธ wakeup()
, ์ ๊ธ ํด์ , ์ค์ IREAD
๊ทธ๋ฆฌ๊ณ ์ ํ sleep(ip+2)
-์ด ๋ชจ๋ ์ ์ writep()
์ฃผ๊ธฐ๋ฅผ ๋ค์ ์์ํฉ๋๋ค.
์ด๊ฒ์ผ๋ก ์ XNUMXํ์ ํ์ดํ๋ผ์ธ ์ค๋ช ์ ๋ง์นฉ๋๋ค. ๊ฐ๋จํ ์ฝ๋, ๊ด๋ฒ์ํ ์ํฅ.
Xv6, ๊ฐ๋จํ ์ ๋์ค ๊ณ์ด ์ปค๋
ํต์ ๋ง๋ค๋ ค๋ฉด
์ฝ๋์๋ ๋ช
ํํ๊ณ ์ฌ๋ ค ๊น์ ๊ตฌํ์ด ํฌํจ๋์ด ์์ต๋๋ค. pipealloc()
:
#define PIPESIZE 512
struct pipe {
struct spinlock lock;
char data[PIPESIZE];
uint nread; // number of bytes read
uint nwrite; // number of bytes written
int readopen; // read fd is still open
int writeopen; // write fd is still open
};
int
pipealloc(struct file **f0, struct file **f1)
{
struct pipe *p;
p = 0;
*f0 = *f1 = 0;
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
goto bad;
if((p = (struct pipe*)kalloc()) == 0)
goto bad;
p->readopen = 1;
p->writeopen = 1;
p->nwrite = 0;
p->nread = 0;
initlock(&p->lock, "pipe");
(*f0)->type = FD_PIPE;
(*f0)->readable = 1;
(*f0)->writable = 0;
(*f0)->pipe = p;
(*f1)->type = FD_PIPE;
(*f1)->readable = 0;
(*f1)->writable = 1;
(*f1)->pipe = p;
return 0;
bad:
if(p)
kfree((char*)p);
if(*f0)
fileclose(*f0);
if(*f1)
fileclose(*f1);
return -1;
}
pipealloc()
ํจ์๋ฅผ ํฌํจํ๋ ๋๋จธ์ง ๊ตฌํ์ ๋ชจ๋ ์ํ๋ฅผ ์ค์ ํฉ๋๋ค. piperead()
, pipewrite()
ะธ pipeclose()
. ์ค์ ์์คํ
ํธ์ถ sys_pipe
์์ ๊ตฌํ๋ ๋ํผ์
๋๋ค.
Linux 0.01
Linux 0.01์ ์์ค ์ฝ๋๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ๊ทธ์ ์ฐ๊ตฌ์์ ํ์ดํ๋ผ์ธ์ ๊ตฌํ์ ์ฐ๊ตฌํ๋ ๊ฒ์ด ์ ์ตํ ๊ฒ์
๋๋ค. fs
/pipe.c
. ์ฌ๊ธฐ์์๋ ํ์ดํ๋ผ์ธ์ ๋ํ๋ด๋ ๋ฐ inode๊ฐ ์ฌ์ฉ๋์ง๋ง ํ์ดํ๋ผ์ธ ์์ฒด๋ ์ต์ C๋ก ์์ฑ๋ฉ๋๋ค. XNUMXํ ์ฝ๋๋ฅผ ํตํด ํดํน์ ํ๋ค๋ฉด ์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์
๋๋ค. ๊ธฐ๋ฅ์ ์ด๋ ๊ฒ ์๊ฒผ์ด์ write_pipe()
:
int write_pipe(struct m_inode * inode, char * buf, int count)
{
char * b=buf;
wake_up(&inode->i_wait);
if (inode->i_count != 2) { /* no readers */
current->signal |= (1<<(SIGPIPE-1));
return -1;
}
while (count-->0) {
while (PIPE_FULL(*inode)) {
wake_up(&inode->i_wait);
if (inode->i_count != 2) {
current->signal |= (1<<(SIGPIPE-1));
return b-buf;
}
sleep_on(&inode->i_wait);
}
((char *)inode->i_size)[PIPE_HEAD(*inode)] =
get_fs_byte(b++);
INC_PIPE( PIPE_HEAD(*inode) );
wake_up(&inode->i_wait);
}
wake_up(&inode->i_wait);
return b-buf;
}
๊ตฌ์กฐ์ฒด ์ ์๋ฅผ ๋ณด์ง ์๊ณ ๋ inode ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ธฐ ์์
์ ๊ฒฐ๊ณผ๊ฐ SIGPIPE
. ๋ฐ์ดํธ ๋จ์ ์์
์ธ์๋ ์ด ๊ธฐ๋ฅ์ ์์ ์์ด๋์ด์ ์ฝ๊ฒ ๋น๊ตํ ์ ์์ต๋๋ค. ์ง์ ๋
ผ๋ฆฌ sleep_on
/wake_up
๊ทธ๋ ๊ฒ ์ธ๊ณ์ธ์ฒ๋ผ ๋ณด์ด์ง ์์ต๋๋ค.
์ต์ Linux ์ปค๋, FreeBSD, NetBSD, OpenBSD
๋๋ ์ต์ ์ปค๋์ ์ฌ๋นจ๋ฆฌ ๊ฒํ ํ์ต๋๋ค. ๊ทธ๋ค ์ค ์ด๋ ๊ฒ๋ ์ด๋ฏธ ๋์คํฌ ๊ธฐ๋ฐ ๊ตฌํ์ ๊ฐ์ง๊ณ ์์ง ์์ต๋๋ค(๋๋์ง ์์ต๋๋ค). Linux์๋ ์์ฒด ๊ตฌํ์ด ์์ต๋๋ค. ์ธ ๊ฐ์ง ์ต์ BSD ์ปค๋์๋ John Dyson์ด ์์ฑํ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๊ตฌํ์ด ํฌํจ๋์ด ์์ง๋ง ์๋ ๋์ ์๋ก ๋๋ฌด ๋ฌ๋ผ์ก์ต๋๋ค.
์ฝ๋ค fs
/pipe.c
(๋ฆฌ๋
์ค์์) ๋๋ sys
/kern
/sys_pipe.c
(*BSD์์) ์ง์ ํ ํ์ ์ด ํ์ํฉ๋๋ค. ๋ฒกํฐ ๋ฐ ๋น๋๊ธฐ I/O์ ๊ฐ์ ๊ธฐ๋ฅ์ ๋ํ ์ฑ๋ฅ ๋ฐ ์ง์์ ์ค๋๋ ์ฝ๋์์ ์ค์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ ํ ๋น, ์ ๊ธ ๋ฐ ์ปค๋ ๊ตฌ์ฑ์ ์ธ๋ถ ์ฌํญ์ ๋ชจ๋ ๋งค์ฐ ๋ค์ํฉ๋๋ค. ์ด๊ฒ์ ๋ํ์์ ์ด์ ์ฒด์ ์
๋ฌธ ๊ณผ์ ์ ํ์ํ ๊ฒ์ด ์๋๋๋ค.
์ด์จ๋ ๋ช ๊ฐ์ง ์ค๋๋ ํจํด(์: SIGPIPE
๊ทธ๋ฆฌ๊ณ ๋์๊ฐ๋ค EPIPE
๋ซํ ํ์ดํ๋ผ์ธ์ ์ธ ๋) ์ด ๋ชจ๋ ๋งค์ฐ ๋ค๋ฅธ ์ต์ ์ปค๋์์. ์๋ง๋ PDP-11 ์ปดํจํฐ๊ฐ ์ค์ ๋ก ์๋ํ๋ ๊ฒ์ ๋ณผ ์๋ ์์ ๊ฒ์
๋๋ค. ํ์ง๋ง ์ ๊ฐ ํ์ด๋๊ธฐ ๋ช ๋
์ ์ ์์ฑ๋ ์ฝ๋์์ ์ฌ์ ํ ๋ฐฐ์ธ ์ ์ด ๋ง์ต๋๋ค.
2011๋
Divi Kapoor๊ฐ ์์ฑํ ๊ธฐ์ฌ "
์ถ์ฒ : habr.com