áá
á˝áá á áŠáááľ á¨ááá ááľáĽ á¨á§á᧠ááľááŽá˝á áľáá ፠ááááťá. " á áá áááľ á á
áᥠá¨áᣠááŁáĽá á á°áá°á ááአá ááááá˘
áľá áá áĽáŤááŤá áá?
á¨á§á᧠ááľááŽá˝ "ááááŁáľ á áŠáááľ ááľáĽ á áŁá á áľáááá áá áŤ" áá¸á - á¨áŠáááľ áá°á¨áłá áľááá˝ ááŽááŤáá˝á á¨ááááľ áááľáá áĽá á¨ááłááá á¨áľáĽáá ááľáá áááááĄ-
$ 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 áá áááááľ 2 áĽá 3 áááŽá˝á ᨠdup4 áá "áĽáá°áá áá°ááá"á˘
á¨á§á᧠ááľááŽá˝ á¨áá, ááá á¨ááá ááľáĽ áŤááá áá¨á áááá ἠá¨á ááąá áá°áľ áá¤áľ á ááá áá ááťá áĽá áá° áá áá°áľ ááľáĽ ááľááŁáľ áááá áłá. á áá¤áąá, á°á¨á᪠ááĽáśá˝á áĽá á¨á˛áľá áŚáłá áĽááŁáááá. ááá áá á¨á§á᧠ááľááŽá˝ áááŤá áááá˝á á¨ááľáááľ á¨á áá á áá áá¸ááĄ-
áá°áą á¨áŁáś á¨á§á᧠ááľáá áááá ἠá¨áá¨á¨, á¨ááŤ
read(2)
ááᥠáĽáľáŞáá áľá¨áľ ááááᢠá ááľ áá°áľ áá° áá á¨á§á᧠ááľáá áááťá á¨áá¨á¨, á¨ááŤwrite(2)
á˝ááá ááá ááá á á áá¨á á¨á§áá§á áĽáľáŞáá ἠáľá¨áľ ááááá˘
áá áĽáá° POSIX ááľáááľáŁ áá
á áľááá ááĽá¨áľ ááᥠáĽáľá¨ á§áá§á áľá¨áľ ááťá PIPE_BUF
áŁááľ (á˘áŤááľ 512) á áśáá ááá á ááŁá¸á áľááá
áá°áśá˝ á á§áá§á á áŠá áĽááľ á ááľ áááŁáĄ á áá˝áá áľ ááááľ áá°á á áááá˝ (áĽáá°ááá
á áááľ ááľáľááá˝ á¨ááá°áĄ)á˘
á áá°á á ááá á ááľ áá°áľ áááá áá¤áśášá áá° áĽáą áá˝áá áĽá áá° áá áá°áľ áŤáľá°ááááᢠááá áá°áśá˝ á á ááŤáŤ áľáአááľ ááľáĽ áá°áŠ áá˝ááᣠá¨áá ááááľ ááľá¨á፠áá´á (áĽáá° á´ááá) á áá áá áľáááá ááá áľá ááá ἠáá ááá áĽááľ á áĽááľ áááłáá ᢠááááŁáá˝ á¨áá áá á˝áá áŤáľáááá˘
áá áĽá¨áááá áá?
áááᣠáĽáá´áľ áĽáá°áá°áŤ áááááľ ááá áĽáá˛áááá á áŁáśáź áá áĽáááťáá. á áá á°á¨ áľááľáł ááľáĽ ááľ áĽá á¨á°áá°á áááł ááá°áĽ áŤáľáááááłáᢠáááĽá á¨áá áŁá ááŤá ááľáĽ ááá¨á áĽá áááľáááľ á°ááŁáŤáľ áŤáľáááááłáᢠá ááá ááááá˝ áá á ááŁáĽ áĽá á ááá áá á°ááŁáŤáľá áááĽáŤáľ á ááłááľ áááá፠áŤáľáááááłáᢠáĽá á¨áá á¨á°ááááá áአáŁá ᪠ááá°áá á áááááŤáá˝ áŤáľáááá.
ááá˝ áŤááááá á¨á ááᎠáá´áá˝áá ááá¨ááἠááá ááľá áááľá¨á á áá á¨á¨áááá ááá áŽáľ á á°áá ááĽáŤáľ ááĽáŤáľ ááá á¨á ááá ááᢠáá áá áá áááá á á áááŽá˝ ááá áááá˘
á¨áľ áá á¨áááááá?
á¨áłááá áá˝áá á
áᏠá¨áľ áĽááłá á ááá
áá˘
á TUHS áá á°á ááľáĽ ááá ááá¨áá áĽáá°áááĽááľ ááᢠá¨á፠áłáŞáŤá˝áá áá¨áľ áĽáá˝ááá áĽá áĽááá á áá áááŽá˝ á¨á áŽá áŤá´áśá˝ áĽá á áľááśá˝ á áĽááą áááááľ ááááľ áááłáľ áĽá¨áľ á á¨áĽáŤááᢠáĽá á ááá á¨á ááľá áĽáááŤá áááĽáŤáŽá˝ á áá á á ááááá˘
áľá á§áá§á áĽááłá áłáŞá áŤááá á¨ááá áááľ áŤááá, áááááá áááá áŽááá˝á áááá¨áľ áĽáá˝ááá.
á áááŤá˝á áá, pipe
á á°áá á¨áĄ ááľáĽ á¨áľáááľ áĽáŞ ááĽá 42 áá sysent[]
. á á ááŁá?
áŁá áá áŠáááľ á¨áááá˝ (1970-1974)
ááá áąáŤ á áááááᢠpipe(2)
ááľáĽá á áááĄáá˘
TUHS áĽáá˛á
áááá˘
áŚáľá°áá á¨áŠáááľ áĽáľá á¨áá¨á¨áťá áĽáľá á á°áĽáłá˘ ááľáĽ á¨á°áá á¨ááá ᣠáá á°áá á¨á§á᧠ááľáá áá á¨ááááŞáŤá áľáŞáľ ááᢠáĽ.á¤.á . á 1973 ᣠáŚáľá°ááá áĽáľá áááťáťá áĽáŤ á ááŤááľ áá áá á ᣠáŽááá á C áĽáá°áá á°áá ᣠáĽáá á áŤá°áá á¨áŠáááľ áĽáľá á°ááá°á˘
á ááľ á ááŁá˘ áśá ááŞááŽá "ááŽááŤáá˝á áĽáá° á¨á áľáááľ áąáŚ áááááľ" á¨áááá ááłáĽ áŤáá¨á á áľá á°ááľ áľáŤá á áááˇá.
á áĽáŞáŤá á¨ááááá áá˝áá ááľáĽ
áŠáááľ áĽá á˛áᣠááŽáŽá˛áá˝ áŤáá áá á á¨áľááá° ááááá á°áŤá˛ áŹá áśááá°áá á á ááľ áá°áľ áá á¨á°áááá áá¨á áá° ááłáŞáŤá áĽáť áłááá áá° áá áá°áľ áááŁáąáá áĽááľáá áľ áĽááľá áá á áľááááᢠáŹá á¨ááťá ááľááľ áá áᢠááá ᣠáĽáá° áá á°ááᾠᣠáĽáŤááłááą á¨áľáááľ áŁá ᪠ááá áá áĽáá˛áŤááľ áááááᢠá áá°áśá˝ ááŤá¨á á ááĽáł ááá á áĽáááą áá° ááŤá¨áá ááá á¨ááá áľáá áĽá á ááá? áĽá á ááľáĽ áľá "á§áá§" áĽá á¨áá°áśá˝ ááľá°ááĽá á ááŁáĽ ááá፠áá á ááľ á¨á°áá°á ááłáĽ áłááἠáĽáť áŹá á áá¨á¨áť âá á°ááááá!â áĽá áŽá¸á˘
áĽá á á°á¨áᢠá ááľ á áľá°áłá˝ áá˝áľ áŹá á¨ááá áĽá áźá áááŚáŁ ááĽá áľ áĽáá´áľ áĽáá°ááá á (á¨á§á᧠ááľáá ááᣠáá˝áá) áĽá á¨ááá áľáá˝á áááá¨á á ááŤáł áá°á á ááŽááŤáá˝á á áľá°áŤáááᢠá áááĽáá áá á¨á§á᧠ááľááŽá˝ á áá°áá áŞáŤáá˝ ááľáĽ á áŁá á á°áá áĽá á áá áááá. á áłáááą áááŁá°á áá á¸ááááš á°ááśá˝á á¨áá á áááŁáŞ áá° á áłáá áááá á°á á áááŁá¸ááᢠá¨á°áá°á áá á ááᣠáŹá á¨á§á᧠ááľáá á á áááá á¨ááŤá áá ááᎠáĽá á áá á áááľ á¨ááá áľááááśá˝ ááá á áá áááá á¤áá á áĽá á ááŁáĽ á°ááˇáá˘
áĽáá° á áááłá°á áá á¨áśáľá°áá áĽáľá áŠáááľ á¨ááá ááá áŽáľ á ááˇáᢠáĽá ááá áĽááłá á¨á¨ááá ááá áŽáľ á ᲠááľáĽ á¨á°áťá á˘ááá
á¨á°ááľ á˝áá á ááᢠpipe(2)
á¨áááąá á¨á°ááá, áľááá
á°ááśášá á áááá áááá áá˝áá pipe(2)
á á á°áŁáłá˘ á¨á°áťá áĽá á ááľ ááá ááá áĽáť ááááłáᣠáá á áľááľá á¨áá á ááá áá á°ááŁá áŤáááŁááĄ-
á¨áľáááľ áĽáŞ áąáŚ á¨á§á᧠ááľáá á¨ááŁá ᨠI/O áá´á áááĽáŤáᢠá¨á°ááá°á ááá ááá áááŁáĽ áĽá áááá áľáŤ áá ááá áá˝ááᢠá ááľ ááá áá° á§áá§á á˛áťá áĽáľá¨ 504 áŁááľ áłáł ááááᣠá¨á፠á áá á¨á áťáťá áá°áą áłááˇáᢠá¨á§áá§á ááľáĽ á ááŤááĄá áľ áá, á¨áłá¸áá áá¨á ááá°áłá.
á áááĽáá áááľ á¨ááá á C ááľáĽ áĽáá°áá á°á˝áá áĽá pipe(fildes)
"
á¨áľáááľ áĽáŞ áąáŚ á¨á§á᧠ááľáá á¨ááŁá ᨠI/O áá´ áááĽáŤáᢠá¨á°áááąáľ á¨ááá ááááá˝ á ááŁáĽ áĽá á ááá áľáŤáá˝ ááľáĽ áĽá á áá ááá áá˝áá. á ááľ ááá áá° á§áá§á á˛áťáᣠáááá á r1 (resp. fildes [1]) á°áááś áĽáľá¨ 4096 áŁááľ ááἠááľ áá áááᣠá¨á፠á áá á¨ááťá áá°áą áłááˇáᢠá¨á§áá§á áá á ááŤááĄá áľ áá ááá áá° r0 (resp. fildes [0]) á°ááá° áááĄá áááľáłá.
á ááľ áá á¨á§á᧠ááľáá á¨á°ááḠá áá áááľ (ááá á¨á፠á áá) ááľá°ááĽá áá°áśá˝ (á ááŁá áĽáŞáá˝ á¨á°áá áŠ) áĽáá°áá ááłá°áŁá. áŤá) áĽáŞáá˝á á áá áá á¨á§áá§á áá áá¨áá áŤáľá°áááá áŤááĽáĄ и áťá.
ááá á á§á᧠ááľáá á áŠá á¨á°ááááľá á¨ááľááŤá áá°áśá˝á áááá°á á ááŁáĽ á ááá˘
á ááľ áŤá áĽáť áŤáá á¨áŁáś á¨á§á᧠ááľáá (ááá á¨áłá¸á áá¨á á¨ááá) áááá ἠá¨áá°á¨á áĽáŞáá˝ (ááá á¨ááá ááá á°ááá°áá) "á¨ááá áá¨á¨áť" ááááłáᢠá á°ááłáłá áááł áĽáŞáá˝á ááá á˝á ááŁááá˘
ááááŞáŤ
áŠáááľ áľáľáľá°á áĽáľá (1975)
á¨áŠáááľ ááá áŽáľ ááá ἠá áááá áá
ááĽá áááłáľ áá˝áá á áá áśá˝ á¨á¤á ááĽáľ á᪠á áŠáááľ á¨ááá áá áŤáá áĽá¸áá á°ááľ áá áᢠá¨áľáľáľá°áá áĽáľá áááľ ááá áŤá á¨áááť áŽáľ áĽáá˛á áá á˘áá áľá á°áŁá°áá áĽáľá áááľ áá áá áá ááľá áľáááá áá˝áá á áá-áἠá¨á˝áááľ ááŞá á°á°áŤááˇáá˘
áᏠá¨áá˝ááá áľáá á¨á
áľááľ á
á ááááľ áá˝áá, áá
á á˝áá á°ááŞáá˝á á áŽáá áá áŤáłáŤá. áĽá áĽááá°áááá áá¨á áśáá (ᨠTUHS ááŽáááľá á¨ááá¨á)ᣠááá¨áľ áá˝ááá˘
á¨15 áááłáľ á ááľáŁ á ááľáĽ á¨áá¨á áá á¨ááá áŽáľ á á áťááŠá˘ á áá áśá˝ááááŤáąá á¨áĽá á á áĽáŤáľ á¨áááłáá ááá˝ á ááá˝ á ááá°áľáŠáľáᢠTUHS áĽáľáŤáá á ááá á¨áᣠáĽá á¨áľáŽ áááŽá˝á ááááľ á ááťááŠáᢠáá á 1988 ᨠPDP9 áŽáááŠá°á ááľáŹ áŤáá 11 áľáŤáŽá˝ áŤáá á áŽá á´á á ááá ᢠáá ፠áĽáá°áá áááá á áŁá á¨áŁáľ áá áᣠááá áá á áĽááááš áááá˝ á 1979 ááááľ á¨á°á°á¨áá áľ áŤáá°ááŤ/usr/src/ áá áá áᣠáá á á ááá áĽááłá áááľááᢠáĽáą á°áŁá°áá áĽáľá áá áᣠááá PWB á°áá˝áŚáŁ áĽáŹ á á°áĽáŠá˘
áááąá áĽáá° áá°á¨áľ á áľáá ááľá áááŽášá á áĽá áá° áľáľáľá°áá áĽáľá áááł á ááľá á áľáááŤááᢠá¨áŽáą ááá á ááľ á áááľ áá áááˇáᣠá¨áá á áľááš ááłá¨á áá á¨á áľáŁ áááááá ááľáá°áŤ += áá° ááá áŤááá áľ =+ á ááá¨áᢠá¨áá ááá á ááá á°á°áááᣠáĽá á¨áá ááá áá á áá áĽáá°áá ááá áá á¨á áľáŁ áá á áŁá áĽá á áá°ááá˘
áĽá áᏠá ááľáá áá á TUHS á¨áľáľáľá°áá áĽáľá ááá áŽáľ ááá ἠáĽáá˝ááá
á áááŤá˝á áá á ááááŞáŤ áĽá᳠ᣠá¨á¨ááááá áĽá á¨áŞáş áá á áᾠᨠC-code áá áŁá ᪠áĽáą ááᢠá áá ááááŤ. á áŁá˘áŤáŹ áá á á áááŤáááľ á áŁáĽ á¨ááłáŤ áŚáłá áááá á á°á á ááľááľ áłáá°áá á ááŁá˘áá˝á ááľááŁáľ á¨áťááŠáľ áĽá áá á áá°ááá˘
á ááááŞáŤ áá
/*
* 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
á¨ááá ááá áááá ἠáĽá á ááĽáł ᨠáááťá ááá áááľáŁá 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
. á ááááŞáŤ á˘ááśáá áááá á ááĽá (á¨áá
á áłá˝ áááá¨áą plock
/prele
).
á¨ááŤá á¨á˘ááľ áááłá¨áŞáŤáá ááĽá áĽáááľáťáá. á¨á§áá§á áááąá áŤáá˝ áááľ áĽáľáŤá áľá¨áľ ááŁáŞá 2 ááá á áá áľ. áá° á ááľ áááá áĽááááá (á¨. rp->f_inode
), áľááá
ááŁáŞá ᨠ2 áŤáá° á¨áá, áá
áááľ á¨ááŁáĽ áá°áą á¨á§áá§áá áŤá áááˇá áááľ áá. á áá á áááá, áá° áá á¨á§á᧠ááľáá áááťá áĽá¨áá¨áá áá, áá
á áľá
á°áľ áá. á¨ááááŞáŤá á¨áľá
á°áľ áŽáľ EPIPE
áĽá ááááľ SIGPIPE
á áŠáááľ áľáľáľá°á áĽáľá áá áłá¨.
ááá áá ááááŁá áááľ á˘ááá, áá ááá áá˝áá. á áá áááł, áááááŤáá áĽááááá áĽá áá áá°áľ á¨á§áá§á ááľáĽ áĽáá˛áá ἠáĽá á ááľáĄ á á áŚáł áĽáá˛ááá á°áľá á ááľá¨á áĽáá°ááá. á¨áĽáá ááá˝á áľááá áá° ááááŞáŤá áĽááááłáá, áááááŤáá áĽáá°áá á áá ááĽáá áĽá á á˛áľ á¨ááťá áá°áľ áĽááááŤáá.
á á§áá§á ááľáĽ á á áá áŚáł áŤá, á¨ááŤá á áá áá ááἠáĽáá˝ááá 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 áĽááľááá ááá áĽá áá° á§áá§á áááťá á¨áááá áááááá áá°áľ áááááľ áĽááááŤáá. ááááŁá á˛áá, áĽááááá. 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
ááľáĽ á¨á°á°áá ᨠáá á
á፠ááá˘
Linux 0.01
á¨ááááľ 0.01 ááá áŽáľ ááááľ áá˝ááᢠá áĽáą ááľáĽ á¨á§á᧠ááľááŽá˝á áľáá ፠ááĽááľ á áá áááá fs
/pipe.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;
}
á¨ááá
á ááşáá˝á áłáááá¨áą áĽááłáᣠá¨á˝áá á á°áŤá áá¤áąá áá¨ááἠá áááá ááá¨ááἠá¨á˘ááľ ááŁááť áá ፠áĽáá´áľ áĽá
á áá áĽáá°ááá ááá
áá˝ááᢠSIGPIPE
. á¨áŁááľ-áŁááľ áĽáŤ á á°á¨ááŞ, áá
á°ááŁá á¨áá á¨á°á ááąáľ ááłáŚá˝ áá áááááá ááá áá. ááá áĽááłá sleep_on
/wake_up
áĽáááł á áááľááá˘
áááá ááááľ á¨ááááľáŁ FreeBSDᣠNetBSDᣠOpenBSD
á ááłááľ áááá ááŹáá˝á á ááĽááľ ááľáŠáᢠá ááłá¸áá á˘áá á á˛áľá áá á¨á°áá°á¨á° á á°ááŁá á á¨áá¸áá (á áŤáľá°áá á)ᢠááááľ á¨áŤáą á á°ááŁá á á ááᢠááá áĽááłá áśáľáą áááá á¨á˘á¤áľá˛ á áľáłáá˝ á áá áłáá°á á á°ááá áŽáľ áá á¨á°áá°á¨áą á á°ááŁá áá á˘ááá áŁá¨á ááłáľ á áá á ááłá¸á á¨ááá á áŁá á¨á°áአááááá˘
ááá ἠfs
/pipe.c
(á ááááľ áá) ááá sys
/kern
/sys_pipe.c
(á *BSD)ᣠáĽááá°á áŤáľá ááá°á áŤáľááááᢠáĽáá° áŹáá°á áĽá áŤáá°ááłá°á I/O áŤá áŁá
áŞáŤáľ á ááťá¸á áĽá áľáá áᏠá áŽáľ ááľáĽ á áľááá áá¸áᢠáĽá á¨áá
á°á¨ áľááľáł áá°áŁáŁ áááááŤáá˝ áĽá á¨á¨ááá áá
á ááááŽá˝ ááá á áŁá áááŤáŤáᢠá áľááá° ááááá˝ áá á¨ááá˘áŤ áŽááľ áŠáá¨áá˛á˛áá˝ á¨áááááľ áá
á áá°ááá˘
áŤá áá áá
ᣠáĽááľ á¨áአá
áŚá˝á áááŁá´ ááĽá á áľá°áłá˝ áá á (áááłáᣠáááá¨áľ SIGPIPE
áĽá ááááą EPIPE
áá° áá á¨á§á᧠ááľáá á˛á˝á) á áĽááá
áá, á áŁá á¨á°ááŤáŠ, áááá áĽáááĽáá˝. ááá˛-11 áŽáááŠá°áá á ááĽáł áá¨áľ á áá˝áá ááá áá áĽá á¨áááá´ áĽááľ á ááłáľ á ááľ á¨á°áťáá áŽáľ áá áĽá á¨áááá¨á ááá á áá˘
áĽ.á¤.á . á 2011 á á˛áŞ áŤáá á¨á°áťá ᣠá˝áá "
ááá: hab.com