α’αααααααααα·αααααΆα’αααΈααΆαα’αα»ααααααααααα
αααα»αααΊαααααΌααΈαα αααα»αβααΆαβααΆαβααβα
α·αααβααααα·α
βαααβα’αααααβααααΈβαα½αβααΆαβα
αααβααΎαβααΆ "
ααΎααΎααααα»ααα·ααΆαα’αααΈα’αααΈ?
αααααααΊ "αααα ααααΆααΆαα αααααααα·αααααααΆαααααα»ααα αααα»αααΌααΈα" αααααΆαααααααααααααααααααα·ααααΆααΌαααααΆαααααααΌααΈααααα»αααΆαααΆαααααααα·ααΈααΌα ααα½αααααΆ αα·αααΆαααααααααααααΆααααΆααααααααΆαααααααΆααααααΆααα
$ 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()
ααΎααααΈααα½αααΆαα―αααΆαααααΆααααααΆαα½αααΆααα·αααααΆα ααααΎαααΆαααΌααα½αααααααα
α’ααααααααΆαα½α α αΎαααααΎαααΆααα½ααααα’αΆααα·ααααααααΌα
ααααΆααΈα’ααααααααΆααααααααα ααα "ααααΌαααααα" α’ααααααααΆ 2 αα·α 3 ααΆαα½α dup4 ααΎααααΈααααΌαααα stdin αα·α stdout α
ααΎααααΆαααααααα αααααΉαααααΌααααααααααααααααααΎαααΆααα½ααα α―αααΆααα½α α αΎααααααΌαααΆαα ααααΎαααΆααα½αααα ααΎααααΈα’αΆααα·ααααααααΈα―αααΆαα ααΆαααααα ααΎαααΉαααααααααΆαααααΆα αα·αααα αααΆαααΆααααα αααΎαα αααααΆαααΆαααΆααααα ααααααααα αΌααααααααΊααα’αααααΆααα αααΎαααΆαααΆααααααΆαα―αααΆαααααααα’αΆααααα
ααααα·αααΎααααΎαααΆααα½αααααΆααΆαα’αΆαααΈααααααααα αΌαααα
read(2)
ααΉαααΆααΆαααα αΌαααααα·ααααααααΆαα ααααα·αααΎααααΎαααΆααα½αααααΆααΆαααααααα ααΆαααααααααααααwrite(2)
ααΉαααΆααΆαααα αΌαααααα·αααααααααααααααΆααααααΌαααΆαα’αΆαααΈααααααααα αΌαααΎααααΈαααα ααααΆααααααα
ααΌα
ααΆαααααΌαααΆα POSIX αααααΊααΆαααααααααααααα·ααααΆαααα½αα ααΆαααααααα
ααΆααααααααααα αΌααα αΌαααα PIPE_BUF
αα (αααΆαα αα
ααΆαα 512) ααααΌαααααΆα’αΆααΌαα·α ααΌα
ααααααααΎαααΆαα’αΆα
ααΆααααααααΆαα
αα·ααα
ααααΆααααααααααααα αΌααααααααΆααααααααα―αααΆαααααααΆ (ααααα·ααααααααΆαααΆααΆαααααα) αα·αα’αΆα
ααααΎααΆαα
ααΆαα½αααΉαα―αααΆαααααααΆ ααααΎαααΆααα½αα’αΆα αααααααααααααΆααα’ααααααααΆαα ααΆ α αΎααααααΌαααΆαα ααααΎαααΆαααααααααα α¬ααααΎαααΆαα’αΆα ααααΎαααΆααααα»ααααααααΆαααΆα‘ααααΉα αααααααΎααααααΆαααααααααααΆααΆααααα (ααΌα ααΆ semaphore) ααΎααααΈααΌαααααΉααααααααΆαα αα·ααα ααα’αααΈααΆααααα ααααΆαααααα α¬α’αΆαα Conveyors αα½αααααααααααΎαααΈαααα αΆααΆααα’αααααα
ααΎααΎααααα»ααααααααα’αααΈ?
αααα»αααΉααααααααα ααΎααααΆααααααααααα»αααΎααααΈααααΎα±ααααΆααΆααααααΆααααα½ααααααΆααα’ααααααα»αααΆααααααααΈαααααααα§ααααααααααΌαα’αΆα ααααΎαααΆαααΆαα α’αααααΉαααααΌααααα ααααα·ααααααα’αΆαααα αα·αααααΆαααΆααα½αα ααα½ααα αααα»αααα·α α’αααααΉαααααΌαααΆααα»αααΆαααΎααααΈαααααα αα·ααα»ααα·ααααααα ααααΈααα·ααααααα’αΆααααα α’αααααΉαααααΌαααΆαα§ααααααα½αα ααα½αααΎααααΈα α αα»αααΆαααα‘α»ααααααααα·ααααα·ααΆαα’αΆα αα·ααααααααΎα’ααααααααΆα―αααΆαα α αΎαααΆαα αΆααααααΊα αΆαααΆα αααΎααααΈα’αα»ααααα’αΆαααααα·αα·ααΆαα·ααααααααΆααα·αααααΆααΆαααΎα
α₯α‘αΌαααα ααΎαααΆαααααααααα½ααα½α ααΆααα αΎα ααΎααααΈααΆααα½ααααααααΌαααααΊααα ααααααααααΊα αααααααααΊα αααΆαα ααΎααααΈαααααΆαα α¬ααα·αααααααΌααααΌαα α·ααααα·αα αααΆααααΆααααααααΎαα ααα»ααααααααΌαααααααααα½αααΆαα·α αα αααααΆααα’αααΈααααα·αααΆαααααΉααα»αα
ααΎααΎααααα»αααααΎααα α―ααΆ?
αααα»ααα·αααΉαααΆα
αααΆααα
ααααααααα
ααααααΈααααΆααααααααα»ααα
α―ααΆααα
ααΆαααΎαααααααΆααααααααΆα TUHS ααΊααΌα ααΆααΆααα ααααααΆααΆααααααΈαα ααΎαα’αΆα ααΎααααααααα·ααΆααααααααααΆαα αααααααααααααΎα α αΎααααα»αααΆαααΆαααααα αααααα·α αα αα·αααααααΉααααααααΆα αααΎαααααΆαααΎααααΈαααααα·αααΌααααααΆααααΆααα’αααααααααα·α αααααααΈααΆααα αα·αααααΈαα αΆααα α αΎαβαααα»αβααΉαβαααΆαβα αααΆααβα’αααΈβαααααβααΆαααααβαααβαα βααΆααα
ααααααα α·αααααΉαααΆαα ααααΉαα ααααΎαααααααΎαα’αααΈαααααααα·αα»ααΆαααααααααααα αΌαααααα ααΎαα’αΆα ααΎαααααΌαααααΎααααααΆααααΆαααααααααα
ααααα·ααΈααα, pipe
ααΊααΆααΆαα α
ααααααααααα 42 αα
αααα»αααΆααΆα sysent[]
. α
ααααα?
ααΊααα Unix αααααααΈ (1970-1974)
αααα»ααα·αααΆαααααΎαααΆαααΆαα½αααα pipe(2)
αα·ααα
αααα»α
TUHS α’αα’αΆαβααΌα
αααα
ααΆαααααα»αααααΎαααΈ 1973 ααααΌααΈαααΊααΆααααα α»αααααααααααΆαααΊααααααααααααα αααα»αα§αααααααααΆαα ααα»ααααααααΆααααααααΌααααααΆαααααααααααα αααα»αααα‘α»αααααΆα XNUMX ααΆαααΆααααα»αααααΎαααΆαααΎααααΈαααααα’ααΆαααααα»αααααΎαααΈ XNUMX ααΊαααααααΌαααΆααααααα‘αΎααα·ααα αααα»α C α αΎαααΌα ααααααΆαααααα»αααααΎαααΈ XNUMX ααααΌααΈαααΆαααΎαα
α’αααα’αΆαααααΆααααΆαααααΎαααΆααααααα―αααΆαααα Doug McIlroy ααααΎαααα·ααα "ααΆαααααΆαααααααα·ααΈααΌα ααΆαα»αααα½α"α
αα
αααα»αααααα
αααα Brian Kernighan
αα αααααα Unix ααΆααααα αΆααααα½α α ααααα αααΌαα α·ααααααααααα»αα αααα coroutines ααΆαααααΎα±αααααα»ααα»αα±ααα’ααααα·αααα OS ααΊ Ken Thompson α’αα»ααααΆαα±αααα·αααααααααααΆαααααααα ααααΎαααΆααα½αα ααα½ααα·αααααΉααααα ααΆααα§αααααααα»ααααααα ααα»αααααααααΆαααα ααΆααααααΎαααΆααααααααααααααα Ken αα·αααΆααΆα’αΆα αα αα½α α ααααααΆαααΆααααα αααα»αααΆαααΆα’αααααΌα ααΆα ααΆααα ααα±αααααααααααααααααΆααα’ααααΎααα½αααΆαααααΆααα ααΎααΆαααααααααααααΆαααααΆαααααΎαααΆααα·αααΆα’αααααααααααααααΆαααΆαααααααα ααΆααα―αααΆαααααα·ααααααααααα? α αΎαααΆααααα αααααααααα»αααΆαααααΎααααΎααΆααααΆαααα½ααααααΆαααααααα½αα±ααα αΆααα’αΆαααααα "ααααααααα αΌαααααα" αα·αααΆααα·αααααΆα’αααΈααΆαααααααααααααα’ααααααααααααααΎαααΆαααα Ken ααΆαααΆααααΆααααΆ "αααα»αααΉαααααΎααΆ!" α
α αΎαααΆαααααΎα ααααΆα ααααΆααααααΆαααΆαα½α Ken ααΆαααααΆααααααΌαααΊααα αα·αααα αα½ααα»ααααααα·ααΈαααααααΆαααΆα αααΎαααΎααααΈααααααααααααΆαααΈααααααααα½αααααα½αααααΆααααα αΌα (αααα’αΆα ααααΈααααα) αα·αααααΆααααααΌααααααα―αααΆαα αα αααααααααΆαααααααααααΌαααΆαααααΎααααΆαααααΆαααΌααααΌααΆααα αααα»ααααααα·ααΈα αα α α»ααααααΆα α ααααΆαα·ααΆαααΆαααααΎαα½αααααΎααααΈααααΎα―αααΆαααΈαααααα·ααΈααΆαα’ααααααα αααΆαααΈαααααα»αααα ααααα·α ααααααα Ken ααΆααααα½α API ααΎα αα·αααΆααααααααααααααααΆαααα»αααΆαααααΎααααΆαααααααααΆαα½αααΉαα’αα»αααααΆααα’αΆαααΆααα»α αααααααΌαααΆαααααΎααΆααααΈααααααααα
ααΆα’αα»αα ααΌαααααααααααΆααααΊααα Unix ααααα»αααααΎαααΈααΈααααΌαααΆαααΆαααααα α αΎααααααΈααΆααΎαααΆαααΌααααααααΊααααααααααΆ C
ααΎαααΆαα’αααααα―αααΆααααααΆαα pipe(2)
ααΈααΆαα
ααααααΆαααΆααααΈα ααΌα
ααααα’αααα’αΆα
α
αΆααααααΎααααααΆααααααααα―αααΆα pipe(2)
ααααΌαβααΆαβαααααβαα
βαααα»α assembler α αΎαβαααα‘ααβα―αααΆαβαααααΆβααβαα½αβααα»ααααα ααα»ααααβααΆαβαααααβααΌαβαα»αααΆαβααααΌαβαααβααααΉαβαα»αβαα½α
βα αΎαα
ααΆαα α ααΆααααααααα ααααα αααααΎαααααααΆα I/O αααα α ααΆααααααααα αΌαα α’ααααα·αααααΆα―αααΆααααααΆααααα‘αααααα·αα’αΆα ααααΌαααΆαααααΎαααααΆααααααα·ααααα·ααΆαα’αΆα αα·ααααααα αα ααααααα’αααΈαα½αααααΌαααΆαααααααα ααααααααα αΌα ααΆαααα»ααα·αααααααα αΌαααα 504 αα αααααΆααααΈαααααααΎαααΆααααααααααΌαααΆαααα’αΆαα αα αααα’αΆαααΈααααααααα αΌα αα·αααααααααααΆααααΆααααααΌαααΆαααα
αα
ααααΆααααααΆαα ααΊαααααααΌαααΆααααααα‘αΎααα·αααΆ C αα·α pipe(fildes)
Β»:
ααΆαα α ααΆααααααααα ααααα αααααΎαααααααΆα I/O αααα α ααΆ ααααααααα αΌααααααα α’ααααα·αααααΆα―αααΆααααααΆααααα‘αααααα·αα’αΆα ααααΌαααΆαααααΎαα αααα»αααααα·ααααα·ααΆαα’αΆα αα·ααααααα αα ααααααα’αααΈαα½αααααΌαααΆαααααααα ααΆααααααααααα αΌαααα α’ααααα·αααααΆααΆααααα‘αααααα»α r1 (resp. fildes[1]) ααααΌαααΆαααααΎ ααααααα»ααα·αααααααα αΌαααα 4096 αα αααααΆααααΈαααααααΎαααΆααααααααααΌαααΆαααα’αΆαα αα αααα’αΆαααΈααααα α’ααααααααΆαααα‘αααα r0 (resp. fildes[0]) αααα·ααααααα
ααΆααααΌαααΆαααααααααΆαα ααααααααααααα½αααααΌαααΆαααααα ααααΎαααΆαα’ααααααααααΈα (α¬α αααΎα) (αααααΎαα‘αΎααααααΆαα’αααΆαααΆαααΆαααααααααΆαα αα) ααΉααααααΌααα·ααααααααΈααααααααααααΎααΆαα α ααΌααααα α’αΆα ΠΈ ααααα.
αααααΆαααΆααααααααααααααααΆαααααααα’αΆααααΈααα’αααααααααΎαααΆαααααααααΆααααΆαααααααααα
ααΆαα α ααΌααααααα α’αΆαααΈααααααααα αΌαααα (αα·αααΆααα·αααααααααααΆααααΆαα) αααααΆαα α»αααααΆα (α’ααααααααα―αααΆαααΆααα’ααααααΌαααΆααα·α) αααα‘αα "α α»ααααα ααααα―αααΆα" αα·αα αααααααΆαα α ααΌααααααααα»αααααΆαααΆαααααααααααΆααααα·αααααΌαααΆαα’αΎααΎααα
ααΆααβαααα»α
Unix ααααα»αααααΎαααΈααααΆααα½α (1975)
α
αΆααααααΎαα’αΆαααΌααααααααΌααΈα
α’ααααααααααΆα αααΎαααααΆαααααα αα ααΊααΆα―αααΆααααα½αααααα ααΎααΊααα Unix αααααΆααα ααΆααααα Bell Labs α αααααΈααΆα’αΆααααΆαααααααααα»αααααΎαααΈααααΆααα½αα’αα»ααααΆαα±ααααααΌααααααααααΎααΌααααααααααααΆααααα α’αΆααααΆαααααααααα»αααααΎαααΈααααΆαααΈαααΆαααα ααααΌαααααααΆαααα ααΌα ααααααααα ααααΌαααΆαα ααα αΆαααΆα αααΆααα ααααααααααααααααα»αα αααΆααα
ααααααα α’αααα’αΆα
αα·αααααα
αααααααα»αααα‘αΎααα·α αααααααααααααΆαα·ααααα
αααΆαααΈαααα
ααααα α αΎαααΌαα’ααα»αααα Warren Toomey (αααααΆαα
αΆααααααΎααααααα TUHS) α’αααα’αΆα
ααΆαααααΆαα
ααΆα 15 ααααΆααα»α αααα»αααΆαααΆααααα αΌααααα»αα αααΆααα ααααααααΌαααααααααααΆααααααα±αα αααααααΆααααααα»ααα·αα αΌαα α·ααααα»αααΆαααα αααΆααα αααααααααααα»αααΈα ααα½αα αααΆααα ααααααααααααααααα·αααααΆααα TUHS αα·αααΆααααΆααα α‘αΎααα α αΎααααα»ααα·αααΆααα·αααα·α αΌαααααΎαααααα αΆααααα ααα»αααααα ααααΆα 1988 αααα»αααΆαααααΎαααΆαααα αΆαααα½ααααααΆα 9 αααααααΆαααΆαααααα»ααα»αααΈαα»αααααΌααα PDP11 α ααΆαα·ααΆααααα»αααΆαααΉαααΆααΎααΆααααΎαααΆαα¬α’αα ααα»ααααααΆαααΎαααΎ /usr/src/ αα αααααααα―αααΆαααΆαα αααΎαααααΌαααΆααααααΆαααα ααααΆα 1979 αααααΎααα αα»ααΆαα ααΆααΆααΆαααααα»αααααΎαααΈααααΆαααΈα α¬ααΆαα·ααααααααααα» PWB αααα»ααα·αααΆα
αααα»αααΆαααααΆααααααααααΆααΌαααααΆα α αΎαααααααα½ααααααααααααα ααΆααααΆαααΆαααααΆαααααα»αααααΎαααΈααααΆααα½αα αααααααααΌααα αααααα αααααααααΌαααααααα½αααααα·α αααααααΆααααααΌααα·αα·ααααααααΆααααΎα += αα ααΆαααααααΎ =+α α’αααΈαα½αααααΌαααΆααα»αα αααααΆαααΆαααα α αΎαα’αααΈαα½αααααΌααααααα‘αΎααα·αααΆαααααα»α ααα»αααααα·αα αααΎααααααα
α αΎααααααααααΎαα’αΆα
α’αΆαααΆαα’ααΈαααΊαα·ααα
TUHS ααΌαααΌααααααααααΆαααααα»αααααΎαααΈααααΆααα½αα
ααααα·ααΈααα αα glance ααααΌα αααααααα·αααα αααααα C-code αα»ααααα Kernighan αα·α Ritchie ααΊααΆααααααΆα ααΆαααααΈ. ααΆαα·αααΉαααΆααααααααααα»αα’αΆα αααα αΌααααααααΌα αααααΌααααααααΆαααΆαααααααα½ααααΆαααΌααααΌααΆαααΎααααΈα±ααααααΉααααααααα αΆαααΌα α ααα’αααα ααΎααα ααααααααααααα»αα
αα
ααΎαααααΌα
/*
* 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
ααα αααα·ααααααα’αΆαααααα·αααΆαααααΆααααααΌαααα αΆααααΆααααΈααΆαααααα»αααααΎαααΈαα½αα ααα»αααααα ααΈααα ααΎαααΎαααΆ αααααααΆαα―αααΆαααΆααΆαααααΆαα½α ααααααααα αΌαααααααααααααΆααααααΎα―αααΆαααΆαααααααααα»ααααα½α!
α
ααααα―αααΆα 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
file descriptor αααααΆααα’αΆα αα·αα
αΆααααΆααα’ααααααααΆαααααΆααααααααααααααΆααααΈ 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 ααααΌααΈαα
ααα»αααααααααΈααΆ conveyor ααΎαα αα αααααααΆα’αΆα αααα αααα»αααααΈααα ααΎαααααα α αΎαα αΌααααααααααααΉαααΆααααΎαααΆααα½αααααααααααΉαα’αΆαααΈααααααααα αΌαααααα αα·ααααααΎαααα αααααααααααααααΆαααα αααα»ααααα αα αααααΎαααααΆααααΈααααα ααΎααααααααα ααΆαα αΆααααααΎα αααα½αααααααααα α αΎαα αΆααααααΎαααααααααΆααααααααααΈα
ααααα·αααΎααΆαααααααααααααααααααααΆαααα
αααα»ααααααααα ααΎαααααααα·αααααααα
ααΆαααααααΎ 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
αα
inode α ααΎααααααααΈααΆααα‘αΎααα·ααα
0 α αΎαααααΆααΆαααΆααααααΎαααΆαααΆαα½ααααα
ααααααααα
αααααα ααΎαααΉαααΆαα
αααααα conveyor αααα 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()
α
αΆαααα inodes αα αΌαααααα½ααααααα
αα α¬ααα½αααΆααααααα (α§ 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()
α
αΆααααααΎαααααα‘αΎααα·αα
ααααααα ααααΆααα·αααααΆα’αααΈααααααααα αΌαααααααα αααα»αααΆαααααα»αααααΎαααΈααααΆααα½αα ααΌαααΆαααα α’ααααααααΌααααΌααΆαα
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
ααΊβααΆβαααα
ααβαααβααΆαβα’αα»ααααβαα
βαααα»αβ
ααΈαα»α 0.01
α’αααα’αΆα
αααααααααΌαααααααααααΆααααΈαα»α
0.01 α ααΆααΉαααΆαααΆαααααΆααααα»αααΆααα·ααααΆα’αααΈααΆαα’αα»ααααααααααααα αΌαααααααα
αααα»αααααααΆααα fs
/pipe.c
. αα
ααΈααα α’ααΈααΌαααααΌαααΆαααααΎααΎααααΈααααΆαα±ααααααααααα αΌαααααα ααα»ααααααααααααα αΌαααααααααα½αααΆααααΌαααΆααααααααΆα’αααα C ααααΎαα ααααα·αααΎα’αααααΆααα½α
α
αΌαααΆαααααααααΌαααααα»αααααΎαααΈααααΆααα½α αααα’αααααΉααα·αααΆααααα αΆα’αααΈαα
ααΈαααααα αααααΆα’αααΈααααα»αααΆαααΎααα
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
ααΎααα
αα·αα
αααααααα
ααΊαααααΈαα»α ααααΎα, FreeBSD, NetBSD, OpenBSD
αααα»αααΆαααααααΆααααΊαααααααΎααα½αα ααα½ααααΆαααΏαα ααααΆαααααΆααααΆαααααα»αα αααααα½αααααΆαααΆαα’αα»αααααααααΆαααΌαααααΆαααΎααΆα (αα·ααα½αα±ααααααΆααααα’αΎααα) α ααΈαα»α ααΆαααΆαα’αα»ααααααααΆαααααα½αα α αΎααααααΈααΆααΊααα BSD ααααΎαααΆααααΈααΆαααΆαα’αα»αααααααααα’ααααΎααΌααααααααΌαααΆααααααααα John Dyson ααα»ααααΆαααααΆαααααα αα½αααααΆαααααΆααα ααΆαα»αααααΆααααΆααααΈααααΆαα αα·ααα ααα
α’αΆα fs
/pipe.c
(αα
ααΎααΈαα»α
) α¬ sys
/kern
/sys_pipe.c
(αα
ααΎ *BSD) ααΆααααΌαααΆαααΆαααααααα·αααααΆααα ααΆαα’αα»αααα αα·αααΆαααΆαααααααααΆαααααααααα·αααααΌα
ααΆααα·α
ααα αα·αα’ααααΆα I/O ααΆαααΆααααααΆαααα
αααα»αααΌαααΆααααα
αα
α»αααααααααα α αΎαααααααΆααααα’α·αααααΆααααα
ααα’αααα
αα
αΆα ααΆαα
αΆαααα αα·αααΆαααααααα
ααΆααααααααααΊααα ααΆαααΆααα»ααααααααααΆαααΆαααααΆααα ααααα·ααααααΆα’αααΈαααααΆαααα·ααααΆαααααααΌαααΆααααααΆαααααααα·ααααΆααααΆαα’αααΈααααααααααααα·ααααα·ααΆααααααα
αααα»αααααΈααΆααααα ααΆααΆααΆααα½αα±ααα
αΆααα’αΆαααααααααααΆαααααα»ααααα»αααΆαααααΎαααααΌα
αΆααααα½αα
ααα½α (α§ααΆα ααα ααΆααααααΎα SIGPIPE
αα·ααααα‘αααααα·α EPIPE
αα
αααααααααα
ααααααα·ααα·α) αα
αααα»αααΆααα’ααααα αα»αααααΆααααΆααααΆαα ααΊαααααααΎαα αααα»ααααα ααααΆαα·ααααααΎααα»αααααΌααα PDP-11 ααααΆαααα ααα»αααααα
ααΆαα
αααΎααααααααΌααααααΈααΌααααααααΌαααΆααααααααΈαααΈααααΆααα»ααααα»αααΎαα
αα·ααααααα Divi Kapoor αααα»αααααΆα 2011 α’ααααα "
ααααα: www.habr.com