á€áá±á¬ááºážáá«ážááẠUnix kernel ááŸá ááá¯ááºááá¯ááºážáá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠáá±á¬áºááŒáááºá áááŒá¬áá±ážáá®á áá±á¬ááºážáá«ážáá
áºáá¯ááºááᯠâá
áááºáá»ááºáááááºâá
áá«ááá¯á·áá¬ááœá±ááŒá±á¬áá±áá¬áá²á
ááá¯ááºááá¯ááºážáá»á¬ážááẠ"Unix ááœáẠá¡áá±ážá¡ááŒá®ážáá¯á¶áž áá®ááœááºááŸá¯ááŒá áºááá¯ááºáááº" - áááá¯ááááºáááºáá»á¬ážááᯠá á¯á ááºážáá¬ážááá·áº Unix á á¡áááºážáᶠáá¿áá á¡áááá¹áá«ááºááœáá·áºááá¯áá»ááºááŸáá·áº áááºážááŸá®ážáá±á¬ command-line áá±á¬ááºáá¯ááºá
$ echo hello | wc -c
6
á€áá¯ááºáá±á¬ááºááá¯ááºá
áœááºážááẠkernel-áá±ážáá±á¬á
áá
áºáá±á«áºááá¯ááŸá¯á¡áá±á«áº áá°áááºáááºá pipe
á
á¬ááœááºá
á¬áááºáž á
á¬áá»ááºááŸá¬áá»á¬ážááœáẠáá±á¬áºááŒáá¬ážáá«áááºá
ááá¯ááºááá¯ááºážáá»á¬ážááẠáá¯ááºáááºážá ááºá¡áá»ááºážáá»ááºáž áááºááœááºááŸá¯á¡ááœáẠáá áºáááºážááœá¬áž áááºážááŒá±á¬ááºážááᯠáá¶á·ááá¯ážáá±ážáááºá ááá¯ááºááá¯ááºážááœáẠá¡áááºáá áºáᯠ(áá±ážáááºá¡áá¯á¶áž) ááŸáá·áº á¡ááœááºáá áºáᯠ(áááºáááºá¡áá¯á¶áž) áá«ááŸááááºá ááá¯ááºááá¯ááºážá ááá·áºááœááºážááŸá¯ááœáẠáá±ážáá¬ážáá±á¬ á¡áá»ááºá¡áááºááᯠá¡ááœááºááœáẠáááºááá¯ááºáááºá
ááá¯ááºááá¯ááºáž áá±á«áºááá¯ááŸá¯ááá¯á·ááŒáá·áº áááºáá®ážáá¬ážááŒááºáž ááŒá áºáááºá
pipe(2)
ááá¯ááºáá±á¬áºááŒáá»ááºááŸá áºáá¯ááᯠááŒááºáá±ážááá·áºá áá áºáá¯ááẠááá¯ááºááá¯ááºážá ááá·áºááœááºážááŸá¯ááᯠáááºááœáŸááºážááŒá®ážá áá¯áááááŸá¬ á¡ááœááºááá¯á· áá±ážááá¯á·áááºá
á¡áááºáá« command á០trace output ááẠááá¯ááºááá¯ááºážáá áºáᯠáááºáá®ážááŒááºážááŸáá·áº áááºážááŸáááá·áº áá±áá¬á á®ážáááºážááŸá¯ááᯠááŒááááº-
$ 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()
áá°ážááœá²ááá¯ááºáá±á¬áºááŒáá»ááºááá°áááºá ááá±ážáá¯ááºáááºážá
ááºáá
áºáá¯ááẠááá¯ááºáá±á¬áºáá°áá
áºáŠážáᶠá
á¬áá±ážááŒá®áž á¡ááŒá¬ážáá¯ááºáááºážá
ááºáá
áºáá¯ááẠá¡ááŒá¬ážáá±á¬áºááŒáá°áá¶á០áá°áá®áá±á¬áá±áá¬ááᯠáááºáááºá shell ááẠstdin ááŸáá·áº stdout ááá¯á·ááᯠááá¯ááºáá®á
á±ááẠ2 ááŸáá·áº 3 ááᯠdup4 ááŒáá·áº á¡áááºááŒá±á¬ááºážáááºá
ááá¯ááºááá¯ááºážáá»á¬ážáááŸááá«á shell ááẠprocess áá áºáá¯á output ááᯠááá¯ááºáá áºáá¯ááá¯á· áá±ážááŒá®áž file á០data ááá¯áááºááẠá¡ááŒá¬áž process áá áºáá¯ááá¯á· ááá¯ááºááœá¬ážááááºááŒá áºáááºá ááááºá¡áá±ááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠá¡áááºážá¡ááŒá áºáá»á¬ážááŸáá·áº áá áºááºáá±áá¬ááᯠááá¯ááá¯ááŒá¯ááºážáá®ážááœá¬ážáááºááŒá áºáááºá ááá¯á·áá±á¬áºá ááá¯ááºááá¯ááºážáá»á¬ážááẠáá¬áá®ááá¯ááºáá»á¬ážááᯠááŸá±á¬ááºááŸá¬ážáá¯á¶ááẠááá¯áá±á¬ááºážáááº-
áá¯ááºáááºážá ááºáá áºáá¯ááẠááá¯ááºááá¯ááºážá¡ááœááºáá áºáá¯á០áááºáááºááŒáá¯ážá á¬ážáá«áá ááá¯á·áá±á¬ááº
read(2)
áá±áá¬áááŸáááá¯ááºáááºá¡ááááááºááá¯á·áááá·áºáááºá áá¯ááºáááºážá ááºáá áºáá¯ááẠááá¯ááºááá¯ááºážá¡ááŒáá·áºá¡á á¯á¶ááá¯á· á á¬áá±ážáááºááŒáá¯ážá á¬ážáá«ááwrite(2)
áá±ážááẠááá¯ááºááá¯ááºážá០á¡áá»ááºá¡ááẠáá¯á¶áá±á¬ááºá áœá¬ ááááºááá»ááºáž ááááºááá¯á·ááœá¬ážáá«áááºá
POSIX ááá¯á¡ááºáá»ááºáá²á·ááá¯á·á á€á¡áá¬ááẠá¡áá±ážááŒá®ážáá±á¬ááá¯ááºááá¯ááºááŸá¯áá
áºáá¯ááŒá
áºáááº- ááá¯ááºááá¯ááºážá¡áá á
á¬áá±ážáá«á PIPE_BUF
ááá¯ááºáá»á¬áž (á¡áááºážáá¯á¶áž 512) ááẠáá¯á¶ááŸááºááá¯ááºáá»á¬áž (ááá¯áá²á·ááá¯á·áá±á¬ á¡á¬ááá¶áá»ááºáááŸááá±á¬) ááááá¯ááºááá·áºáááºážáááºážááŒáá·áº ááá¯ááºááá¯ááºážááŸáááá·áº áá¯ááºáááºážá
ááºáá»á¬ážá¡áá»ááºážáá»ááºáž áááºááœááºááá¯ááºá
á±ááẠá¡ááºáááºááŒá
áºááá«áááºá
áá¯á¶ááŸááºááá¯ááºáá áºáá¯ááŒáá·áºá áá¯ááºáááºážá ááºáá áºáá¯ááẠáááºážá output á¡á¬ážáá¯á¶ážááᯠáááºážáá¶áá±ážááŒá®áž á¡ááŒá¬ážáá¯ááºáááºážá ááºáá áºáá¯ááá¯á· áá±ážááá¯á·ááá¯ááºáááºá ááá¯á·ááá¯áẠáá¯ááºáááºážá ááºáá»á¬ážááẠá á¬áá±ážááŒááºáž ááá¯á·ááá¯áẠáááºááŒááºážááŒá®ážáá¯á¶ážááŒááºážá¡ááŒá±á¬ááºáž á¡áá»ááºážáá»ááºáž á¡áááá±ážááẠááŒááºáá¡áá»ááºááŒááŒááºáž ááá¹ááá¬áž (áááºáááá¯ážáá²á·ááá¯á·) ááᯠá¡áá¯á¶ážááŒá¯á áááºáá²áá±á¬á¡ááŒáá¯ááºáá¯ááºááœáẠáááºáááºááá¯ááºáááºá áááºáá°ááá¯á·áá±á¬ááºáá±ážáá»á¬ážááẠá€á¡áááºá¡áá²á¡á¬ážáá¯á¶ážá០áá»áœááºá¯ááºááá¯á·ááᯠáááºáááºáá«áááºá
áá«ááá¯á· áá¬ááᯠááŸá¬áá±áá¬áá²á
Conveyor á¡áá¯ááºáá¯ááºáá¯á¶ááᯠá áááºáá°ážááŒáá·áºááá¯ááºá á±ááẠááá·áºáááºáá»á±á¬ááºážáá»á¬ážááŒáá·áº ááŸááºážááŒáá«áááºá áááºááẠááŒá¬ážáá¶áá áºáá¯ááŸáá·áº áááºááá¯áá®ááœáẠá¡áá»áá¯á·áá±á¬ á¡ááŒá±á¡áá±áá»á¬ážááᯠááœá²áá±áá±ážááẠááá¯á¡ááºáááºááŒá áºáááºá ááŒá¬ážáá¶ááŸáá±áá¬áá»á¬ážááá·áºáááºááŸáá·áº áááºááŸá¬ážááẠáá¯ááºáá±á¬ááºáá»ááºáá»á¬áž ááá¯á¡ááºáá«áááºá file descriptors áá»á¬ážááœáẠread and write operations á¡ááœááºáž áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠáá±á«áºááẠá¡áá±á¬ááºá¡áá°áá á¹á ááºážá¡áá»áá¯á· ááá¯á¡ááºáááºááŒá áºáá«áááºá á¡áááºááœááºáá±á¬áºááŒáá¬ážáá±á¬ á¡áá°ážá¡ááŒá¯á¡áá°áá»á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá¡ááœáẠáá±á¬á·áááºááŸá¯áá»á¬áž ááá¯á¡ááºáá«áááºá
áá»áœááºá¯ááºááá¯á·á ááá±áá¬áá±á¬ á áááºááá¯ááºážááá¯ááºáá¬áá¯á¶á á¶ááᯠá¡áááºááŒá¯ááẠááá¯á·ááá¯áẠáááºáá±ááŒááẠáá±á¬ááºááá±á¬ áá®ážá¡áááºá¡á±á¬ááºááœáẠkernel áá¡áááºážá¡ááŒá áºáá¯ááºááᯠá á áºáá±ážáá±ážááŒááºážááẠá¡áááºááá·áºááŒá áºáá±áá«ááŒá®á áá«áá±ááá·áº ááá»áŸá±á¬áºááá·áºáá¬ážáá²á·á¡ááœáẠá¡ááŒá²ááŒááºáááºáá¬ážáá«á
áá«ááá¯á·áááºááá¯ááŒáá·áºáá±áá¬áá²á
áá»áœááºáá±á¬á·áºáá²á·áá¬áááºááŒá®ážá
á¬á¡á¯ááºáá
áºá¡á¯áẠáááºááŸá¬ááŸááá²ááááá°ážá
TUHS áá±á¬áºááœááºážááá¯ááºáá»á¬ážááᯠááŸáá·áºáááºááŒáá·áºááŸá¯ááŒááºážááẠááŒááá¯ááºááá¯á· áááºáááºááŒááºážááŸáá·áº áá°áááºá áá»áœááºá¯ááºááá¯á·á áá»áŸáá±áá¬ážáá±á¬ áááá¯ááºážááŒá±á¬ááºážááᯠááŒáá·áºááŸá¯ááá¯ááºááŒá®áž á€á¡ááŒá±á¬ááºážá¡áá¬á¡á¬ážáá¯á¶ážááᯠáááºáááºáá±á¬ááºážáá»á¬ážááŸáá·áº áá¯á¶ááŸáááºá ááºáá»á¬ážá០áá áºáááºážáááºážááŒáá·áº ááŒááºáááºááá°ááẠááŸá áºáá±á«ááºážáá»á¬ážá áœá¬ ááŒáá¯ážá á¬ážá¡á¬ážáá¯ááºááŸá¯á¡ááœáẠáá±ážá á¬ážááŸá¯ááŸááá«áááºá ááŒá®ážáá±á¬á· áá»á±á¬ááºáá¯á¶ážáá±áá² á¡ááá¯ááºážá¡á ááœá±ááᯠáá« áá±á¬ááºážáá±á¬ááºážáááááºá
ááá¯ááºááá¯ááºážáá»á¬ážá ááŸá±ážáá±ááºáááá¯ááºážááŒá±á¬ááºážááᯠáá»áœááºá¯ááºááá¯á·á áááá»ááºá áááºááᯠáá»á±áááºá áœá¬ááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠáá±ááºáá®á¡á°ááá¯ááºáá»á¬ážááᯠááŸáá¯ááºážááŸááºááŒáá·áºááá¯ááºáá«áááºá
á
áá¬ážáá
ááº, pipe
ááá¬ážááŸá á
áá
áºáá±á«áºááá¯ááŸá¯áá¶áá«áẠ42 ááŒá
áºáá«áááºá sysent[]
. ááá¯ááºááá¯ááºááŸá¯?
ááá¯ážáᬠUnix kernels (1970â1974)
áá¬áá²ááœááºá
á០ááŸá¬áááœá±á·áá°ážá pipe(2)
ááááºáá°áž
TUHS á á€ááá¯á·ááá¯áááºá
Unix ááááááá¯ááºáá±ááŸá¯ááẠassembler ááŒáá·áºáá±ážáá¬ážáá¬ážáá±á¬ kernel ááŒáá·áºáá±á¬ááºáá¯á¶ážáá¬ážááŸááºážááŒá áºááŒá®ážá ááá¯ááºááá¯ááºážáá»á¬ážáá«ááŸááá±á¬ááááá¬ážááŸááºážáááºážááŒá áºáááºá 1973 áá¯ááŸá áºá¡ááœááºážá ááááá¡ááŒáááºáá¯ááºáá±ááŸá¯ááᯠááá¯ááá¯áá±á¬ááºážááœááºá¡á±á¬ááºáá¯ááºáá±á¬ááºáá±áá²á·ááŒá®áž kernel ááᯠC ááŒáá·áº ááŒááºáááºáá±ážáá¬ážáá²á·áááºá ááá¯á·ááŒá±á¬áá·áº Unix á á áá¯áá¹áááŒá±á¬ááºáá¯ááºáá±ááŸá¯ááᯠááœá±ážááœá¬ážáá²á·áááºá
Doug McIlroy á "á¥áá»á¬ááºááá¯ááºáá²á·ááá¯á· áááá¯ááááºáá»á¬ážááᯠáá»áááºáááºááŒááºáž" áá°áá±á¬ á¡áá°á¡áááᯠDoug McIlroy á០á¡ááá¯ááŒá¯áá¬ážááá·áº á á¬áááºážáá áºáá¯ááᯠá á¬áááºáá° áá áºáŠážá០ááœá±á·ááŸááá²á·áááºá
Brian Kernighan áá
á¬á¡á¯ááºááœááº
Unix áá±á«áºáá¬áá±á¬á¡áá«á Coroutines áá»á¬ážá¡ááœáẠáá»áœááºá¯ááºá áá«ááá¬ááẠá¡áá»áá¯á·áá±á¬ áá¯ááºáááºážá ááºááœáẠáá±ážáá¬ážáá¬ážáá±á¬ áá±áá¬áá»á¬ážááᯠá ááºáá á¹á ááºážááá¯á·áá¬áá á¡ááŒá¬ážáá±á¬ áá¯ááºáááºážá ááºááá¯á· ááœá¬ážáááºáááºáž ááœáá·áºááŒá¯ááẠOS áá±ážáá¬ážáá° Ken Thompson á¡á¬áž áá±á¬ááºážááá¯áá²á·áááºá Ken á ááŒá áºááá¯ááºáááºááá¯á· áááºáá²á·áááºá ááá¯á·áá±á¬áº á¡áááºážáááºáá»áŸáᬠááŒá áºáá±á¬ááŒá±á¬áá·áº á áá áºá¡ááºá¹áá«áááºááá¯ááºážááᯠá¡áá±ážáá«áá±á¬ á¡áááºážááá¹áá០áá«áááºá á±ááá¯áááºá áá¯ááºáááºážá ááºáá»á¬ážááŒá¬ážááœáẠááá¯ááºááá¯ááºáá±ážáá¬ážááŒááºážááẠá¡áááºá¡áááºááá¯ááºáá áºáá¯ááá¯á· á á¬áá±ážááŒááºážááẠááŒá®ážáá¬ážáá±á¬ á¡á¬ážáá¬áá»ááºáá áºáá¯áá¬ážá ááœááºááá¯ááºáá±á¬á¡ááẠ"ááá¯ááºááá¯ááºáž" ááŸáá·áº áá¯ááºáááºážá ááºáá»á¬ážá á¡ááŒááºá¡ááŸááºáááºááœááºááŸá¯ááá¯ááºáᬠá¡áá¬ážá¡ááá¯áá±á¬áºááŒáá»ááºááá¯á·ááŸáá·áºá¡áá° áááá»áá±á¬á¡ááá¯ááŒá¯áá»ááºáá áºáá¯ááŒá¯áá¯ááºáá±á¬á¡áá«ááŸáᬠKen á áá±á¬ááºáá¯á¶ážááœáẠ"áá»áœááºáá±á¬áºáá¯ááºáá«á·áááº!"
ááŒá®ážáá±á¬á· áá¯ááºáá²á·áááºá áá¶ááŒáá¹áá¬áá áºáá¯áá±á¬ ááá±áááºážáá áºáá¯ááœáẠKen ááẠkernel ááŸáá·áº shell ááá¯ááŒá±á¬ááºážáá²áá¬á áááºážááá¯á·ááá·áºááœááºážáá¯á¶ááá¯áááºáá¶áá¯á¶ (ááá¯ááºááá¯ááºážáá áºáá¯ááŸááŒá áºááá¯ááºáááº) ááá¯á á¶áááºááŸááºááẠá á¶áááá¯ááááºáá»á¬ážá áœá¬ááᯠááŒááºáááºááŒá®áž ááá¯ááºá¡áááºáá»á¬ážááᯠááŒá±á¬ááºážáá²áá²á·áááºá áá±á¬ááºáá áºáá±á·ááœáẠááá¯ááºááá¯ááºážáá»á¬ážááᯠá¡áá¯á¶ážáá»ááŸá¯ááœáẠá¡ááœááºááœááºáá»ááºá áœá¬ á¡áá¯á¶ážááŒá¯áá²á·áááºá áááºááá¹ááááºá¡áá¯ááºááœááºá á¡ááœááºážáááºáá»á¬ážááẠáááºážááá¯á·ááᯠword processors áá»á¬ážá០á á¬ááœááºá á¬áááºážáá»á¬ážááᯠprinter ááá¯á·áá±ážááá¯á·ááẠá¡áá¯á¶ážááŒá¯áá²á·áááºá ááá¡ááŒá¬ááœáẠKen ááẠáá°á API ááŸáá·áº syntax ááᯠááá¯ááºááá¯ááºážáá»á¬ážá¡áá¯á¶ážááŒá¯ááŸá¯ááᯠááááºááááºážá á¡áá¯á¶ážááŒá¯áá²á·ááá·áº ááá·áºááŸááºážáá±á¬ááœááºáááºážááŸááºážáá»á¬ážááŒáá·áº áá¯ááºááá¯ážááẠá¡á á¬ážááá¯ážáá²á·áááºá
áá¶ááá±á¬ááºážá
áœá¬ááŒáá·áºá áááááá¯ááºáá±áá±á¬ Unix kernel á¡ááœáẠá¡áááºážá¡ááŒá
áºáá¯áẠáá»á±á¬ááºáá¯á¶ážááœá¬ážáá«áááºá áá»áœááºá¯ááºááá¯á·ááœáẠC ááŒáá·áºáá±ážáá¬ážáá¬ážáá±á¬ kernel á¡áááºážá¡ááŒá
áºáá¯ááºááŸááá±á¬áºáááºážá
áá»áœááºá¯ááºááá¯á·ááœáẠá
á¬ááœááºá
á¬áááºážá¡ááœáẠá
á¬áá¬ážáá»á¬ážááŸááááºá pipe(2)
áá¯ááºáá±ááŸá¯ááŸá
áºáá¯áá¯á¶ážááŸá ááá¯á·ááŒá±á¬áá·áº áááºááẠá
á¬ááœááºá
á¬áááºážááᯠááŸá¬ááœá±ááŒááºážááŒáá·áº á
áááºááá¯ááºáááºá pipe(2)
assembler ááŒáá·áº áá±ážáá¬ážáá¬ážááŒá®áž ááá¯ááºáá±á¬áºááŒáá»ááºáá
áºáá¯áᬠááŒááºáá±ážáááºá ááá¯á·áá±á¬áº áá»áŸá±á¬áºááá·áºáá¬ážááá·áº á¡ááá áá¯ááºáá±á¬ááºááá¯ááºá
áœááºážááᯠáá±ážáá±á¬ááºáá¬ážááŒá®ážááŒá
áºáááº-
á áá áºáá±á«áºááá¯ááŸá¯ ááŒáœáẠááá¯ááºááá¯ááºážáá¯áá±á«áºáá±á¬ I/O ááá¹ááá¬ážáá áºáá¯ááᯠáááºáá®ážáááºá ááŒááºáá¬áá±á¬ ááá¯ááºáá±á¬áºááŒáá»ááºá¡á¬áž áááºááŸá¯ááŒááºážááŸáá·áº áá±ážááŒááºážááá¯ááºáᬠáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá¡ááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá áá áºáá¯áá¯ááᯠááá¯ááºááá¯ááºážááá¯á· á á¬áá±ážáá±á¬á¡áá«á áááºážááẠáá±áᬠ504 bytes á¡áá buffers áá±ážááŒá®ážáá±á¬áẠá á¬áá±ážááŒááºážáá¯ááºáááºážá ááºááᯠááá¯ááºážáá¶á·áá¬ážáááºá ááá¯ááºááá¯ááºážááŸáááºááá·áºá¡áá«á buffed áá±áá¬ááá¯áá°áááºá
áá±á¬ááºáá
áºááŸá
áºááœááºá kernel ááᯠC ááŒáá·áº ááŒááºáááºáá±ážáá¬ážááŒá®ážááŒá
áºáááºá pipe(fildes)
"
á áá áºáá±á«áºááá¯ááŸá¯ ááŒáœáẠááá¯ááºááá¯ááºážáá¯áá±á«áºáá±á¬ I/O ááá¹ááá¬ážáá áºáá¯ááᯠáááºáá®ážáááºá ááŒááºáá±ážáá¬ážáá±á¬ ááá¯ááºáá±á¬áºááŒáá»ááºáá»á¬ážá¡á¬áž áááºááŸá¯ááŒááºážááŸáá·áº áá±ážáá¬ážááŒááºážáá¯ááºáááºážáá»á¬ážááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá ááá¯ááºááá¯ááºážááá¯á· áá áºá á¯á¶áá áºáá¯ááᯠáá±ážááŸááºáá±á¬á¡áá«á áá±á¬áºááŒáá»ááºááẠr1 (resp. fildes[1]) ááᯠá¡áá¯á¶ážááŒá¯ááŒá®áž áá±áᬠ4096 bytes á¡áá áá¶ááá¯ááºáááºááŸááá±á¬á ááá¯á·áá±á¬áẠáá±ážáá¬ážááŸá¯áá¯ááºáááºážá ááºááᯠáááºááá¯ááºážááá¯ááºáá«áááºá ááá¯ááºááá¯ááºážá០áááºáá±á¬á¡áá«á áá±á¬áºááŒáá»ááºááẠr0 (resp. fildes[0]) ááá¯á· ááŒááºááœá¬ážáᬠáá±áá¬ááᯠáá°áááºá
ááá¯ááºááá¯ááºážáá áºáᯠáááºááŸááºááŒá®ážáááºááŸáá·áº á¡ááŒááºá¡ááŸáẠá¡áá»áá¯ážááŒá¯ááá·áº áá¯ááºáááºážá áẠááŸá áºáᯠ(ááá¯á·ááá¯ááº) áá±á¬ááºáááºááœá² áá±á¬ááºážááá¯ááŸá¯áá»á¬ážááŒáá·áº áááºáá®ážáááºáᯠáá°ááá«áááºá á¡áá²áá»áááº) áá±á«áºááá¯ááŸá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á ááá¯ááºááá¯ááºážá០áá±áá¬ááᯠáá±ážááá¯á·áá«áááºá ááẠО áá±ážáá¬áž.
shell ááœáẠááá¯ááºááá¯ááºážááŸáá áºááá·áº áá»áááºáááºáá¬ážáá±á¬ linear array á processes ááᯠáááºááŸááºáááºá¡ááœáẠsyntax áá áºáá¯ááŸááááºá
á¡áá¯á¶ážáá áºáá¯áá¬áá«ááŸááá±á¬ ááá¯ááºááá¯ááºážá¡ááœááºáá áºáá¯á០áááºááẠáá±á«áºááá¯ááŸá¯áá»á¬ážááẠá¡áá¯á¶ážáá áºáá¯áá¬áá«ááŸááá±á¬ (ááá¯ááºáá±á¬áºááŒáá»ááºá¡á¬ážáá¯á¶ážááᯠááááºáá¬ážáááº) "ááá¯ááºáá¡áá¯á¶áž" ááá¯á· ááŒááºááœá¬ážáááºá á¡áá¬ážáá°á¡ááŒá±á¡áá±áá»áá¯ážááœáẠáá±á«áºááá¯ááŸá¯áá»á¬ážááᯠáá»á áºáá»á°ááŸá¯áá¬ážáááºá
á¡á
á±á¬áá¯á¶áž
Unix Sixth Edition (1975)
Unix á¡áááºážá¡ááŒá
áºáá¯ááºááᯠá
áááºáááºáá«á
ááŸá áºáá±á«ááºážáá»á¬ážá áœá¬ á á¬á¡á¯áẠááŒááºá¹áá±á· Bell Labs ááŒááºáááœááºáááŸáááá¯ááºáá±á¬ Unix kernel ááœááºáá áºáá¯áááºážáá±á¬á á¬ááœááºá á¬áááºážááŒá áºáááºá ááá¹áááá¯ááºáá±ááœáá·áºááá¯ááºá ááºááẠááá¬áá»á¬ážá¡á¬áž áááºážáá¡áááºážá¡ááŒá áºáá¯ááºááᯠá¡áá¯á¶ážááŒá¯ááœáá·áºáá±ážáá±á¬áºáááºáž ááá¹áááá¯ááºáá±ááœáá·áºááá¯ááºá ááºááẠáááºážááŒá áºááá¯ááºáá»á±ááᯠáááºáá¯ááºáá¬ážáá±á¬ááŒá±á¬áá·áº á á¬á¡á¯ááºááᯠááá¬ážáááẠáááºááŸáááºá ááºáááá¹áá°áá»á¬ážááŒáá·áº ááŒáá·áºáá±áá²á·áááºá
ááá±á·áááºááẠáááá¹áá°ááœáẠáá»á±á¬ááºážáá¬ážáá»á¬ážááᯠáá¯á¶áá±á¬áºáá¬ážááá·áº á
á¬á¡á¯ááºá á¡áá¯á¶ážááᯠááŒááºáááºáá¯á¶ááŸáááºáááá¹áá°ááᯠáááºáááºááá¯ááºááẠá TUHS ááá±á¬áá»ááºááᯠá
áááºáá²á·áá° Warren Toomey á áá»á±ážáá°ážááŒá±á¬áá·áº áááºááẠáá±á«ááºážáá¯ááºááœá²ááá¯ááºáá«áááºá
ááœááºáá²á·áá±á¬ 15 ááŸá áºáá»á±á¬áºá áá»áœááºáá±á¬áº áá±ážáá¬ážáá±á¬ source code á áááá¹áá°ááᯠááá¯ááºááá·áºáá²á·áá«áááºá ááŒááºá¹áá±á·áá¬ááŒá±á¬áá·áºáá² ááá¯áá±á¬á· áá»áœááºáá±á¬áºááááá²á· á¡ááŒá¬ážáá±á¬áºáá®ááœá±áá²á· á¡áááºá¡ááœá±ážááᯠáááŒáá¯ááºááá¯á·áá«á TUHS áááŸááá±ážáá«á áá»áœááºá¯ááºááẠá¡áááºážá¡ááŒá áºáá±á¬ááºážáá»á¬ážááá¯á· áááºáá±á¬ááºááœáá·áºáááŸááá«á áá«áá±ááá·áº 1988 ááŸá¬ PDP9 ááœááºááŒá°áá¬ááá± á¡áááºáá°ážáá¬ážáá²á· 11 áá¯ááºáá«áá²á· ááááºááœá±á¡áá±á¬ááºážááᯠáá»áœááºáá±á¬áºááœá±á·áá²á·áááºá á¡áá¯ááºáá¯ááºááá¬ážááá¯áᬠááááá¯á·áááºáá«áááºá áá«áá±ááá·áº ááá¯ááºá¡áá»á¬ážá á¯ááᯠ1979 ááá¯á· á¡ááŸááºá¡áá¬ážááŒá¯áá¬ážáá²á· áááá¯á¡ááá¯ááºáž /usr/src/ áá áºáááºáá áºááẠááŸááá²á·áá«áááºáá á¡á²áá®áá¯ááºážááááºáž ááŸá±ážáá±ááºááá¯á·áá±á¬áẠáááºááá«áááºá áááºážááẠááá¹ááááŒá±á¬ááºáá¯ááºáá±ááŒááºáž ááá¯á·ááá¯áẠPWB áááºážáááºáá¬ááŒááºážááŒá áºáááºáᯠáá»áœááºáá±á¬áºáááºáá²á·áááºá
ááŸá¬ááœá±ááŸá¯ááᯠá¡ááŒá±áá¶á¡ááŒá Ạáá»áœááºáá±á¬áºáá°áá²á·ááŒá®áž á¡áááºážá¡ááŒá áºáá»á¬ážááᯠááá¹áááá¯ááºáá±ááŸá¯á¡ááŒá±á¡áá±ááá¯á· ááá¯ááºááá¯ááºáááºážááŒááºáá²á·áááºá áá¯ááºááá áºá áááºáá áºááá¯ááºážááẠá¡áá°áá°áááºááŒá áºááŒá®áž á¡ááá¯ááºážá¡áááºážáááºááᯠáááºážááŒááºááááºááŒá áºááŒá®áž áá±ááºáá® ááá¯ááẠ+= ááᯠá¡áá¯á¶ážáááŒá¯áá±á¬á·áá±á¬ =+ á¡ááŒá áºááá¯á· ááŒá±á¬ááºážáá²ááááºááŒá áºáááºá áá áºáá¯áá¯ááᯠááá¯ážááá¯ážááŸááºážááŸááºáž áá»ááºááá¯ááºááŒá®áž áá áºáá¯áá¯ááᯠáá¯á¶ážáá¯á¶áž ááŒááºáá±ážááá±ááá·áº á¡áááºážááŒá®ážáá±á¬á· ááá¯ááºáá«áá°ážá
ááá±á·áá»áœááºá¯ááºááá¯á·ááẠTUHS áááá¹ááááŒá±á¬ááºáá¯ááºáá±ááŸá¯áá¡áááºážá¡ááŒá
áºáá¯ááºááá¯á¡áœááºááá¯ááºážááœááºáááºááŸá¯ááá¯ááºáááºá
á áá¬ážáá ááºá ááááá áºáá»ááºááœááºá Kernighan ááŸáá·áº Ritchie ááá¯á·ááá¬ááááá¯ááºáá® C-code áá¡áááá¡ááºá¹áá«áááºááŸá¬áááºážá á¡ááá¯áá»á¯á¶áž. áá»áœááºá¯ááºáááá¯ááºááŸá á¡áá±á¬áºáá±ážáá»ááºážááŒá±á¬ááºážáá±á¬ display á§áááá¬ááᯠá¡á¶áááºááœááºáá»ááŒá áºá¡á±á¬áẠáá»ááºáá»ááºááŒáá·áºááŒáá·áºáááºážááŒááºááŒááºážáááŸááá² áá¯ááºá¡ááá¯á¡ááœá¬áá»á¬ážááᯠááá·áºááœááºážááá¯ááºáááºááŸá¬ áááŒá¬ááááá¯ááºáá«á
á
á¡á¥á®ážá
/*
* 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
system call parameters áá²á· return values ââááœá±ááᯠáá»á±á¬áºááœá¬ážáá«ááŒá®á
á
ááºážááŒáá·áºáá¡á±á¬ááº
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);
}
/* ⊠*/
}
ááá¯á·áá±á¬áẠfunction ááᯠreadp()
в pipe.c
ááá¯ááºááá¯ááºážá០á¡áá»ááºá¡áááºááᯠáááºáááºá áá«áá±ááá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááá±á
ááŒá®áž ááŒá±áá¬áá¶áá¬á ááá¯áá±á¬ááºážáá«áááºá writep()
. ááááºá áá¯ááºááẠargument passing convention á ááá±á¬ááá¬áááŒá±á¬áá·áº ááá¯ááá¯ááŸá¯ááºááœá±ážáá¬áá±á¬áºáááºáž á¡áá»áá¯á·áá±á¬á¡áá±ážá
áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠáá»ááºááŸááºáá¬ážááá¯ááºáá«áááºá
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
Unix áááŒá±á¬ááºááŒáááºááŒá±á¬ááºáá¯ááºáá±ááŸá¯ááœááºáááºááŸá¬ážáá²á·áááºá
Conveyor ááœáá·áºáá¬ážáááºáá±á¬áẠááŒáá·áºááœá¬ážááá¯ááºáá«áááºá á€ááá á¹á ááœááºá áá»áœááºá¯ááºááá¯á·ááẠááá¯ááºááá¯ááºážá០á¡ááŒá¬ážáá¯ááºáááºážá ááºááᯠáááºááŒá®áž áááºážááœáẠáá±áá¬á¡áá¯á¶á¡áá±á¬áẠááœááºáá¬áááºáᯠáá»áŸá±á¬áºááá·áºááŒááºážááŒáá·áº áá±á¬á·ááᯠááœáŸááºááŒá®áž á¡áááºáá»á±á¬áºááœá¬ážáá«áááºá áá»áœááºá¯ááºááá¯á·ááá¯ážáá¬áá±á¬á¡áá«ááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡á ááá¯á·ááŒááºááœá¬ážáᬠáá±á¬á·ááá¯áá±á¬ááºáá áºááŒáááºááœá²áá»ááá¯ááºááŒá®áž á á¬áá±ážá ááºáááºážá¡áá áºáá áºáá¯á áááºáááºá
ááá¯ááºááá¯ááºážááœáẠáá±áá¬ááœááºá¡áá¯á¶á¡áá±á¬ááºááŸááá«áá áááºážááá¯á¡áá¯á¶ážááŒá¯á áá±áá¬ááᯠáá±ážáá±ážáá«áááºá i_size1
inode'a (ááá¯ááºááá¯ááºážá¡ááœááºáá
áºáá¯ááẠ0 ááŸáá·áº áá®áá»áŸááá¯ááºáááº) ááẠáááºážááœááºáá«ááŸááá±á¬ á¡áá»ááºá¡áááºáá¡áá¯á¶ážááá¯á· ááœáŸááºááŒáááºá á
á¬áá±ážááá¯á· áá±áá¬á¡áá¯á¶á¡áá±á¬ááºááŸáááẠááá¯ááºááá¯ááºážááá± ááŒáá·áºááá¯á·ááááºá i_size1
ááá¯á· PIPESIZ
. ááá¯á·áá±á¬áẠáá±á¬á·ááᯠááœáŸááºááá¯ááºááŒá®áž ááá¯ááºááá¯ááºážá០áááºááẠá
á±á¬áá·áºááá¯ááºážáá±ááá·áº áááºááá·áº áá¯ááºáááºážá
ááºááá¯áááᯠááá¯ážááŒá¬ážá¡á±á¬áẠááŒáá¯ážá
á¬ážáá«á áá»áœááºá¯ááºááá¯á· ááá¯á¡ááºááá±á¬áẠbytes áá»á¬ážáá»á¬ážáá±ážááá¯ááºááá¬ážááá¯áᬠááŒáá·áºááá¯á· á¡á
ááᯠááŒááºááœá¬ážáá«á á¡áááºáááŒá±áá«áá áá»áœááºá¯ááºááá¯á·ááẠá¡áá¶ááœááºážá
ááºá¡áá
áºááᯠá
áááºááá¯ááºáá«á
áá»á¬ážáá±á¬á¡á¬ážááŒáá·áº parameter áá»á¬áž i_mode
ááœáá·áºááŒá¯áá»ááºáá»á¬ážááᯠááááºážáááºážáááºá¡ááœáẠinode ááᯠá¡áá¯á¶ážááŒá¯áááºá r
, w
О x
. ááá¯á·áá±á¬áº ááá¯ááºááá¯ááºážáá»á¬ážááá
á¹á
ááœááºá á¡áá»áá¯á·áá±á¬ áá¯ááºáááºážá
ááºááẠbits áá¯á¶ážááŒá®áž áá±ážááẠááá¯á·ááá¯áẠáááºááẠá
á±á¬áá·áºáá±ááŒá±á¬ááºáž áá»áœááºá¯ááºááá¯á· á¡áá»ááºááŒáá«áááºá 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()
á¡áá»ááºááŒááŸá¯ááŒáá·áº ááŸá±á¬áá·áºááŸááºááá¯ááºáááºá
ááá¯áá»áœááºá¯ááºááá¯á·ááẠfunction ááá¯áá¬ážáááºáááºá¡áá¬á¡á¬ážáá¯á¶ážááŸááááºá 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()
ááŒá®ážá¡á±á¬áẠááá¯á·ááá¯áẠááááºáá
áºáá¯ááááºá¡áá á¡áá¯ááºááá¯áá
áºáá»á¬ážááᯠáá±á¬á·ááºáá»áá« (ááá¯ááá¯áááºááŸá¬ áá±á«áºááá¯áá«á 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()
áááºážá loop áá€áá±á«áºááá¯ááŸá¯ plock(ip)
á¡áááºááá¯á· ááá±ááá»á¬ ááŒá
áºááœá¬ážáá«áááºá readp()
áááºážá ááááºááá¯á·ááŒááºážááᯠááááºááŸá¬ážááá±ážáá±á¬ááŒá±á¬áá·áº áá¯ááºááẠáá
áºáááºážáááºážááŒáá·áº ááŸááºáááºá
áœá¬ á¡áá¯ááºáá¯ááºááá«áááºá ááŒáá·áºááá¯ááºááẠwakeup()
á¡áá¬áá«ááºááœáẠááœááºáá»ááºááẠá¡ááá·áºááŒá
áºáá±áá±á¬ á¡áááºá
ááºááŒááºážááŒá
áºá
ááºááá¯áᬠá¡ááŸááºá¡áá¬ážááŒá¯ááŒá±á¬ááºáž áááºááŸá¬ážáá«áááºá sched()
ááááºáá² á
áááºáá²á·áá¬áá«á áá«ááŒá±á¬áá·áº readp()
á¡ááŒá±á¬ááºážááá¬ážáá»á¬áž wakeup()
áá±á¬á·ááœáá·áºááŒááºážá á¡á
á¯á¶ IREAD
áá±á«áºááá¯ááŸá¯áá»á¬áž sleep(ip+2)
- áá«ááœá±á¡á¬ážáá¯á¶ážá á¡ááẠwritep()
áááºáááºááŸá¯ááᯠááŒááºáááºá
áááºáááºá
áááºážááẠááá¹áááá¯ááºáá±ááŸá¯ááœáẠááá¯ááºááá¯ááºážáá»á¬ážá¡ááŒá±á¬ááºáž áá±á¬áºááŒáá»ááºááᯠá¡ááŒá®ážáááºáá«áááºá ááá¯ážááŸááºážáá±á¬áá¯ááºá áá»ááºááŒáá·áºáá±á¬áááºáá±á¬ááºááŸá¯áá»á¬ážá
Xv6á ááá¯ážááá¯áž Unix ááŸáá·áºáá°áá±á¬ kernel
ááá¯á·ááŒá
áºáááºá
áá¯ááºááœáẠááŸááºážááŸááºážáááºážáááºáž ááœá±ážáá±á«áºááŒá±á¬áºááŒááºááá¯ááºáá±á¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ áá«ááŸááááºá 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
ááœááºá¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ážáá±á¬ wrapper áá
áºáá¯ááŒá
áºáááºá
Linux ááᯠ0.01
Linux 0.01 á¡ááœáẠá¡áááºážá¡ááŒá
áºáá¯ááºááᯠáááºááŸá¬ááá¯ááºáááºá ááá¯ááºááá¯ááºážáá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ááœáẠáá±á·áá¬ááŸááºáá¬ážá
áá¬áá»á¬áž ááŸááááºá fs
/pipe.c
. á€ááœááºá ááá¯ááºááá¯ááºážááá¯ááá¯ááºá
á¬ážááŒá¯áááºá¡ááœáẠinode ááá¯á¡áá¯á¶ážááŒá¯áá±á¬áºáááºážá ááá¯ááºááá¯ááºážááá¯ááºááá¯ááºá áá±ááºáá® C ááŒáá·áºáá±ážáá¬ážáááºá áááºááẠááááá¯ááºáá±áá±á¬áá¯ááºááŸáá
áºááá·áº ááá·áºáááºážáááºážááᯠhack áá²á·áá»áŸáẠá€áá±áá¬ááœáẠááŒá¿áá¬ááŸááááºááá¯ááºáá«á áá«á function áá²á·áá°áá«áááºá 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;
}
struct á¡áááá¹áá«ááºááœáá·áºááá¯áá»ááºáá»á¬ážááᯠáááŒáá·áºáá²áááºá write operation ááááºááœááºááŸááááŸá á
á
áºáá±ážááẠinode áááºááœáŸááºážááááºážááᯠáááºááá¯á·á¡áá¯á¶ážááŒá¯ááŒá±á¬ááºáž ááœááºáááá¯ááºáááºá SIGPIPE
. byte-by-byte á¡áá¯ááºá¡ááŒááºá á€áá¯ááºáá±á¬ááºáá»ááºááẠá¡áááºáá«á
áááºáá°ážáá»á¬ážááŸáá·áº ááŸáá¯ááºážááŸááºáááºááœááºáá°áááºá áá±á¬á·áá»á
áºááẠsleep_on
/wake_up
ááŒáá¯ááºáá¬ážáá¯á¶ááá±á«áºáá«áá°ážá
áá±ááºáá® Linux Kernelsá FreeBSDá NetBSDá OpenBSD
áá»áœááºá¯ááºááẠáá±ááºáá® á á±á·á¡áá»áá¯á·ááᯠáá»ááºááŒááºá áœá¬ áá»á±á¬áºááŒááºáá²á·áááºá áááºážááá¯á·ááœáẠdisk-based á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá áºáá¯áá»áŸááŸáááŒá®ážááŒá áºááẠ(á¡á¶á·ááŒá áá¬ááá¯ááºáá«)á Linux ááœááºáááºážáááá¯ááºááá¯ááºá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááŸááááºá áá±ááºáá® BSD kernels áá¯á¶ážáá¯ááœáẠJohn Dyson áá±ážáá¬ážáá²á·áá±á¬ áá¯ááºá¡áá±á«áºá¡ááŒá±áá¶á á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá»á¬ážáá«áááºáá±á¬áºáááºáž ááŸá áºáá»á¬ážááŒá¬áá¬áááºááŸáá·áºá¡áá»áŸ áááºážááá¯á·ááẠáá áºáá¯ááŸáá·áºáá áºáᯠááœá¬ááŒá¬ážááœááºážááŸáááºá
áááºááẠfs
/pipe.c
(Linux ááœááº) ááá¯á·ááá¯áẠsys
/kern
/sys_pipe.c
(*BSD) ááœááºá áááºážááẠá¡ááŸááºáááẠá¡ááºááŸá¶ááẠááá¯á¡ááºáááºá vector ááŸáá·áº asynchronous I/O áá²á·ááá¯á·áá±á¬ á¡ááºá¹áá«áááºáá»á¬ážá¡ááœáẠá
áœááºážáá±á¬ááºáááºááŸáá·áº áá¶á·ááá¯ážááŸá¯ááẠááá±á·áá±ááºááœáẠá¡áá±ážááŒá®ážáá«áááºá ááŒá®ážáá±á¬á· áááºááá¯áá®ááœá²áá±ááŸá¯á áá±á¬á·ááºáá»ááŸá¯á ááŸáá·áº áá¬áááºááœá²á·á
ááºážáá¯á¶ááá¯ááºáᬠá¡áá±ážá
áááºá¡áá»ááºáá»á¬áž á¡á¬ážáá¯á¶ážááẠá¡ááœááºááœá²ááŒá¬ážáááºá áááºážááẠáááºáááºááŸá¯á
áá
áºááá¯ááºáᬠááááºáááºáááºáááºážá¡ááœáẠááá¹áááá¯ááºáá»á¬áž ááá¯á¡ááºááá·áºá¡áá¬ááá¯ááºáá«á
áááºááá¯á·áááºááá¯á
á±áá¬áá°á áá¯á¶á
á¶áá±á¬ááºážá¡áá»áá¯á·ááᯠáá±á¬áºáá¯ááºááẠáá»áœááºá¯ááºá¡ááœáẠá
áááºáááºá
á¬ážá
áá¬áá±á¬ááºážááẠ(á¥ááá¬á áááºáá®ážááŒááºážá SIGPIPE
ááŒááºáᬠEPIPE
ááááºáá¬ážáá±á¬ ááá¯ááºááá¯ááºážááá¯á· á
á¬áá±ážááá·áºá¡áá«) á€á¡áá¬á¡á¬ážáá¯á¶ážááœáẠááœá²ááŒá¬ážááŒá¬ážáá¬ážáá±á¬ áá±ááºáá®á
á±á·áá»á¬ážá PDP-11 ááœááºááŒá°áá¬áá
áºáá¯á¶ážááᯠááá¯ááºááá¯ááºááŒááºáá°ážááŸá¬ ááá¯ááºáá±ááá·áº áááœá±ážááẠááŸá
áºá¡áááºážáááºá áá±ážáá¬ážáá²á· áá¯ááºááá± áááºáá°á
áá¬ááœá± á¡áá»á¬ážááŒá®áž áá»ááºáá«áá±ážáááºá
Divi Kapoor á 2011 áá¯ááŸá
áºááœáẠáá±ážáá¬ážáá²á·áááºá
source: www.habr.com