Hōʻike kēia ʻatikala i ka hoʻokō ʻana i nā pipeline ma ka kernel Unix. Ua hauʻoli wau i kahi ʻatikala hou i kapa ʻia ʻo "
He aha kā mākou e kamaʻilio nei?
ʻO Pipelines, "ʻo ia paha ka mea nui loa ma Unix," he ʻano wehewehe o ka manaʻo kumu Unix o ka hoʻopili ʻana i nā polokalamu liʻiliʻi, a me kahi hōʻailona maʻamau ma ka laina kauoha:
$ echo hello | wc -c
6
Aia kēia hana i ke kelepona ʻōnaehana i hāʻawi ʻia i ka kernel pipe
, i wehewehe ʻia ma nā ʻaoʻao palapala
Hāʻawi nā Pipeline i kahi ala unidirectional no ke kamaʻilio interprocess. Loaʻa i ka pipeline kahi hoʻokomo (kākau hope) a me kahi puka (heluhelu hope). Hiki ke heluhelu ʻia nā ʻikepili i kākau ʻia i ka hoʻokomo o ka pipeline ma ka puka.
Hana ʻia ka pipeline me ke kelepona
pipe(2)
, ka mea e hoʻihoʻi i ʻelua faila wehewehe: ʻo kekahi e pili ana i ka hoʻokomo o ka pipeline, ʻo ka lua i ka puka.
Hōʻike ka trace output mai ke kauoha i luna aʻe i ka hana ʻana o ka pipeline a me ke kahe o ka ʻikepili ma o ia mea mai kekahi kaʻina i kekahi:
$ 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
Kahea ka hana makua pipe()
e kiʻi i nā mea wehewehe faila i kau ʻia. Hoʻokahi kaʻina hana keiki e kākau i ka lima hoʻokahi, a ʻo kekahi kaʻina e heluhelu i ka ʻikepili like mai kahi lima ʻē aʻe. Hoʻohana ka shell i ka dup2 e "hōʻano hou" i nā mea wehewehe 3 a me 4 e hoʻokūkū i stdin a me stdout.
Me ka ʻole o nā paipu, pono ka pūpū e kākau i ka hopena o kekahi kaʻina hana i kahi faila a hāʻawi i kekahi kaʻina hana e heluhelu ai i ka ʻikepili mai ka faila. ʻO ka hopena, e hoʻopau mākou i nā kumuwaiwai hou aʻe a me nā wahi disk. Eia nō naʻe, maikaʻi nā pipeline ʻaʻole wale no ka mea e ʻae iā ʻoe e pale i ka hoʻohana ʻana i nā faila manawa:
Inā e hoʻāʻo ana kahi kaʻina e heluhelu mai kahi pipeline ʻole a laila
read(2)
e ālai a hiki i ka loaʻa ʻana o ka ʻikepili. Inā ho'āʻo kahi hana e kākau i kahi paipu piha, a lailawrite(2)
e ālai ʻia a lawa ka ʻikepili mai ka pipeline e hana i ke kākau.
E like me ke koi POSIX, he waiwai nui kēia: kākau i ka pipeline a hiki i PIPE_BUF
ʻO nā bytes (ma ka liʻiliʻi loa he 512) pono ke ʻano atomic i hiki i nā kaʻina hana ke kamaʻilio me kekahi i kekahi ma o ka pipeline ma ke ʻano i hiki ʻole ai i nā faila maʻamau (ʻaʻole hāʻawi i kēlā mau hōʻoia).
I ka hoʻohana ʻana i kahi faila maʻamau, hiki i ke kaʻina hana ke kākau i nā mea i hoʻopuka ʻia iā ia a hāʻawi iā ia i kahi kaʻina hana ʻē aʻe. A i ʻole hiki ke hana i nā kaʻina hana ma kahi ʻano like loa, me ka hoʻohana ʻana i kahi mīkini hōʻailona waho (e like me ka semaphore) e hoʻomaopopo i kekahi i ka wā i pau ai kahi kākau a heluhelu paha. Hoʻopakele nā Conveyors iā mākou mai kēia pilikia āpau.
He aha kā mākou e ʻimi nei?
E wehewehe au iā ia ma nā ʻōlelo maʻalahi i maʻalahi iā ʻoe ke noʻonoʻo pehea e hana ai kahi conveyor. Pono ʻoe e hoʻokaʻawale i kahi buffer a me kekahi mokuʻāina i ka hoʻomanaʻo. Pono ʻoe i nā hana e hoʻohui a wehe i ka ʻikepili mai ka buffer. Pono ʻoe i kahi ala e kāhea ai i nā hana i ka wā heluhelu a kākau i nā hana ma nā faila wehewehe. A pono ʻoe i nā laka e hoʻokō i ke ʻano kūikawā i wehewehe ʻia ma luna.
I kēia manawa ua mākaukau mākou e nīnau i ke kumu kumu kernel ma lalo o ke kukui kukui e hōʻoia a hōʻole i kā mākou kumu hoʻohālike noʻonoʻo. Akā e mākaukau mau no ka mea i manaʻo ʻole ʻia.
Ma hea mākou e ʻimi nei?
ʻAʻole maopopo iaʻu i hea kaʻu kope o ka puke kaulana "
ʻO ka hele ʻana i loko o ka waihona TUHS e like me ke kipa ʻana i kahi hale hōʻikeʻike. Hiki iā mākou ke nānā i kā mākou moʻolelo like, a mahalo wau i nā makahiki he nui o ka hoʻoikaika ʻana e hoʻihoʻi i kēia mau mea āpau mai nā lipine kahiko a me nā paʻi. A ʻike maopopo wau i kēlā mau ʻāpana e nalowale nei.
Ma muli o ko mākou makemake e pili ana i ka mōʻaukala kahiko o nā conveyors, hiki iā mākou ke nānā i nā kernels hou no ka hoʻohālikelike.
Ma ke ala, pipe
ʻo ia ka helu kelepona ʻōnaehana 42 ma ka pākaukau sysent[]
. ʻAkahi?
Kuʻuna Unix kernels (1970–1974)
ʻAʻole i loaʻa iaʻu kahi meheu pipe(2)
ʻaʻole i loko
Wahi a TUHS
ʻO Unix 1973rd Edition ka mana hope loa me kahi kernel i kākau ʻia ma ka ʻōlelo hui, akā ʻo ka mana mua pū me nā pipelines. I ka makahiki XNUMX, ua hoʻokō ʻia ka hana e hoʻomaikaʻi i ke kolu o ka paʻi, ua kākau hou ʻia ka kernel ma C, a no laila ua ʻike ʻia ka paʻi ʻehā o Unix.
Ua loaʻa i kahi mea heluhelu kahi scan o kahi palapala i manaʻo ai ʻo Doug McIlroy i ka manaʻo o "hoʻohui ʻana i nā polokalamu e like me ka hose māla."
Ma ka puke a Brian Kernighan
I ka puka ʻana mai o Unix, ʻo koʻu hoihoi i nā coroutine ua alakaʻi iaʻu e nīnau i ka mea kākau o OS, ʻo Ken Thompson, e ʻae i ka ʻikepili i kākau ʻia i kahi kaʻina e hele ʻaʻole wale i ka hāmeʻa, akā e hoʻopuka pū i kahi kaʻina hana ʻē aʻe. Ua hoʻoholo ʻo Ken e hiki. Eia nō naʻe, ma ke ʻano he minimalist, makemake ʻo ia i kēlā me kēia hana ʻōnaehana e hana i kahi kuleana koʻikoʻi. ʻO ke kākau pololei ʻana ma waena o nā kaʻina hana he pono nui ma mua o ke kākau ʻana i kahi faila waena? ʻO ia wale nō kaʻu i hana ai i kahi manaʻo kikoʻī me ka inoa hopu "pipeline" a me ka wehewehe ʻana i ka syntax no ka launa pū ʻana ma waena o nā kaʻina hana i ʻōlelo hope ai ʻo Ken: "E hana wau!"
A hana. I kekahi ahiahi pōʻino, ua hoʻololi ʻo Ken i ka kernel a me ka shell, hoʻoponopono i nā papahana maʻamau e hoʻohālikelike i ke ʻano o kā lākou ʻae ʻana i ke komo ʻana (hiki ke hele mai mai kahi pipeline), a hoʻololi pū i nā inoa faila. I ka lā aʻe, ua hoʻomaka e hoʻohana nui ʻia nā pipeline i nā noi. I ka pau ʻana o ka pule, ua hoʻohana nā mea kākau ʻōlelo iā lākou e hoʻouna i nā palapala mai nā mea hana huaʻōlelo i ka mea paʻi. Ma hope iki, ua hoʻololi ʻo Ken i ka API kumu a me ka syntax no ka hoʻopili ʻana i ka hoʻohana ʻana i nā pipeline me nā hui hoʻomaʻemaʻe, i hoʻohana ʻia mai ia manawa.
ʻO ka mea pōʻino, ua nalowale ke kumu kumu no ka paʻi ʻekolu o Unix kernel. A ʻoiai ua loaʻa iā mākou ke kumu kumu kernel i kākau ʻia ma C
Loaʻa iā mākou nā palapala kikokikona no pipe(2)
mai nā hoʻokuʻu ʻelua, no laila hiki iā ʻoe ke hoʻomaka ma ka ʻimi ʻana i ka palapala pipe(2)
ua kākau ʻia ma ka ʻōlelo hui a hoʻihoʻi i hoʻokahi wale nō faila wehewehe, akā ua hāʻawi mua i ka hana kumu i manaʻo ʻia:
Kāhea pūnaewele paipu hoʻokumu i kahi mīkini hoʻokomo / puka i kapa ʻia he pipeline. Hiki ke hoʻohana ʻia ka mea wehewehe waihona i hoʻihoʻi ʻia no nā hana heluhelu a kākau. Ke kākau ʻia kekahi mea i ka pipeline, a hiki i 504 bytes o ka ʻikepili i hoʻopaʻa ʻia, a laila hoʻokuʻu ʻia ke kaʻina hana kākau. I ka heluhelu ʻana mai ka pipeline, lawe ʻia ka ʻikepili buffered.
I ka makahiki aʻe, ua kākau hou ʻia ka kernel ma C, a pipe(fildes)
»:
Kāhea pūnaewele paipu hoʻokumu i kahi mīkini hoʻokomo / puka i kapa ʻia he pipeline. Hiki ke hoʻohana ʻia nā mea wehewehe faila i ka heluhelu a kākau ʻana. Ke kākau ʻia kekahi mea i ka pipeline, hoʻohana ʻia ka pahu i hoʻihoʻi ʻia ma r1 (resp. fildes [1]), i hoʻopaʻa ʻia i 4096 bytes o ka ʻikepili, a laila hoʻokuʻu ʻia ke kaʻina hana kākau. I ka heluhelu ʻana mai ka pipeline, ua hoʻihoʻi ka lima i r0 (resp. fildes[0]) e lawe i ka ʻikepili.
Ua manaʻo ʻia i ka manawa e wehewehe ʻia ai kahi pipeline, ʻelua (a ʻoi aku paha) kaʻina hana kamaʻilio (i hana ʻia e nā kelepona ma hope i ke'ō) e hoʻoili i ka ʻikepili mai ka pipeline me ka hoʻohana ʻana i nā kelepona heluhelu и kakau.
Loaʻa i ka pūpū kahi syntax no ka wehewehe ʻana i kahi laina laina o nā kaʻina i hoʻopili ʻia e kahi pipeline.
Kāhea e heluhelu mai kahi paipu ʻole (ʻaʻohe ʻikepili i hoʻopaʻa ʻia) hoʻokahi wale nō hopena (ua pani ʻia nā mea wehewehe faila kākau) e hoʻihoʻi i ka "hopena o ka faila". ʻAʻole mālama ʻia nā kelepona e kākau ma kahi kūlana like.
mua loa
Puka ʻeono o Unix (1975)
E hoʻomaka kākou e heluhelu i ka code source Unix
No nā makahiki he nui ka puke Lions ʻo ia wale nō ka palapala ma ka Unix kernel i loaʻa ma waho o Bell Labs. ʻOiai ua ʻae ka laikini paʻi ʻeono i nā kumu e hoʻohana i kāna code kumu, ua kāpae ka laikini paʻi ʻehiku i kēia hiki, no laila ua puʻunaue ʻia ka puke ma ke ʻano o nā kope kope kope ʻole.
I kēia lā hiki iā ʻoe ke kūʻai i kahi paʻi hou o ka puke, ʻo ka uhi e hōʻike ana i nā haumāna ma kahi mīkini kope. A mahalo iā Warren Toomey (nāna i hoʻomaka i ka papahana TUHS) hiki iā ʻoe ke hoʻoiho
ʻOi aku ma mua o 15 mau makahiki i hala, ua paʻi au i kahi kope o ka code kumu i hāʻawi ʻia Lions, no ka mea ʻaʻole wau i makemake i ka maikaʻi o kaʻu kope mai kahi helu ʻike ʻole o nā kope ʻē aʻe. ʻAʻole i loaʻa ʻo TUHS a ʻaʻole hiki iaʻu ke komo i nā kumu kahiko. Akā i ka makahiki 1988, ua loaʻa iaʻu kahi lipine 9-track kahiko i loaʻa kahi waihona mai kahi kamepiula PDP11. He mea paʻakikī ke haʻi inā e hana ana, akā aia kahi lāʻau /usr/src/ i hoʻopaʻa ʻia i ka hapa nui o nā faila me ka makahiki 1979, ʻoiai he mea kahiko. ʻO ia ka hiku o ka paʻi ʻana a i ʻole kāna huaʻōlelo PWB, e like me kaʻu i manaʻoʻiʻo ai.
Lawe au i ka ʻike ma ke ʻano he kumu a hoʻoponopono lima i nā kumu i ka paʻi ʻeono. Ua mau kekahi o nā code, akā pono e hoʻoponopono iki ʻia kekahi, e hoʻololi i ka hōʻailona += hou i ka =+ kahiko. Ua holoi wale ʻia kekahi mau mea, a pono e kākau hou ʻia kekahi, ʻaʻole naʻe i ka nui.
A i kēia lā hiki iā mākou ke heluhelu ma ka pūnaewele ma TUHS ke kumu kumu o ka paʻi ʻeono mai
Ma ke ala, i ka nānā mua ʻana, ʻo ka hiʻohiʻona nui o ka C-code ma mua o ka manawa o Kernighan lāua ʻo Ritchie pōkole. ʻAʻole hiki iaʻu ke hoʻokomo i nā ʻāpana code me ka ʻole o ka hoʻoponopono nui ʻana e kūpono i kahi wahi hōʻike haiki ma kaʻu pūnaewele.
I ka hoʻomaka
/*
* 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
ʻAʻole i loli ka nui buffer mai ka paʻi ʻehā. Eia naʻe ke ʻike nei mākou, me ka ʻole o nā palapala lehulehu, ua hoʻohana nā pipeline i nā faila i mālama ʻia!
No nā faila LARG, pili lākou
Eia ke kelepona ʻōnaehana maoli 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;
}
Hōʻike maopopo ka manaʻo i nā mea e hana nei. Akā ʻaʻole maʻalahi ka hoʻomaopopo ʻana i ke code, ma muli o ke ala "R0
и R1
Ua hala nā ʻāpana kelepona a me nā waiwai hoʻihoʻi.
E hoao kakou me
pipe()
pono ma R0
и R1
e hoʻihoʻi i nā helu wehewehe waihona no ka heluhelu a me ke kākau ʻana. falloc()
hoʻihoʻi i kahi kuhikuhi i ka hoʻolālā faila, akā "hoʻi" ma o u.u_ar0[R0]
a me kahi faila wehewehe. ʻO ia hoʻi, mālama ke code i loko r
waihona wehewehe no ka heluhelu ʻana a hāʻawi i kahi wehewehe faila no ke kākau pololei ʻana mai u.u_ar0[R0]
mahope o ka lua o ke kahea ana falloc()
.
Ho'āka FPIPE
, ka mea a mākou i hoʻonohonoho ai i ka hana ʻana i ka pipeline, kaohi i ka ʻano o ka hana
/*
* 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);
}
/* … */
}
A laila ka hana readp()
в pipe.c
heluhelu 'ikepili mai ka paipu. Akā ʻoi aku ka maikaʻi o ka ʻimi ʻana i ka hoʻokō e hoʻomaka ana writep()
. Eia hou, ua lilo ke code i mea paʻakikī ma muli o nā kuʻina o ka hoʻopaʻapaʻa ʻana, akā hiki ke waiho ʻia kekahi mau kikoʻī.
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;
}
Makemake mākou e kākau i nā bytes i ka hoʻokomo pipeline u.u_count
. Pono mua mākou e laka i ka inode (e nānā i lalo plock
/prele
).
A laila, nānā mākou i ka helu kuhikuhi inode. I ka wā e wehe ʻia nā ʻaoʻao ʻelua o ka pipeline, pono e like ka counter me 2. Paʻa mākou i hoʻokahi loulou (mai rp->f_inode
), no laila inā ʻoi aku ka liʻiliʻi o ka counter ma mua o 2, ʻo ia ke ʻano o ke kaʻina heluhelu ua pani ʻia kona hopena o ka pipeline. I nā huaʻōlelo ʻē aʻe, ke hoʻāʻo nei mākou e kākau i kahi pipeline i pani ʻia, a he hewa kēia. Kakahi helu kuhi hewa EPIPE
a me ka hoailona SIGPIPE
ua ʻike ʻia ma ka paʻi ʻeono o Unix.
Akā inā hāmama ka conveyor, piha paha. I kēia hihia, hoʻokuʻu mākou i ka laka a hele i ka hiamoe me ka manaʻolana e heluhelu ʻia kahi kaʻina hana hou mai ka pipeline a hoʻokuʻu i kahi ākea i loko. Ma hope o ke ala ʻana, hoʻi mākou i ka hoʻomaka, kau hou i ka laka a hoʻomaka i kahi pōʻai hoʻopaʻa leo hou.
Inā lawa ka hakahaka o ka pipeline, a laila kākau mākou i ka ʻikepili iā ia me ka hoʻohana ʻana i_size1
ma ka inode (inā nele ka pipeline hiki ke like me 0) hōʻike i ka hopena o ka ʻikepili i loaʻa iā ia. Inā lawa ka leo hoʻopaʻa, hiki iā mākou ke hoʻopiha i ka pipeline mai i_size1
i luna PIPESIZ
. A laila hoʻokuʻu mākou i ka laka a ho'āʻo e ala i kekahi kaʻina hana e kali nei e heluhelu mai ka pipeline. Hoʻi mākou i ka hoʻomaka e ʻike inā hiki iā mākou ke kākau i nā bytes e like me kā mākou makemake. Inā hāʻule, a laila hoʻomaka mākou i kahi pōʻai hoʻopaʻa leo hou.
ʻO ka mea maʻamau ka palena i_mode
hoʻohana ʻia ka inode e mālama i nā ʻae r
, w
и x
. Akā i ka hihia o nā pipeline, hōʻailona mākou e kali ana kekahi kaʻina hana no kahi kākau a heluhelu paha me ka hoʻohana ʻana i nā bits IREAD
и IWRITE
pakahi. Hoʻonohonoho ka hana i ka hae a me nā kelepona sleep()
, a ua manaʻo ʻia e hana ʻia kekahi hana ʻē aʻe i ka wā e hiki mai ana wakeup()
.
Hiki ke kilokilo maoli i loko sleep()
и wakeup()
. Hoʻokō ʻia lākou ma
/*
* 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) /* … */
ʻO ke kaʻina hana sleep()
no kekahi alahele, hiki ke hoala ia mai e kekahi kaʻina hana, e kumu wakeup()
no ke ala like. writep()
и readp()
hoʻonohonoho i kā lākou mau hana ma o ia mau kelepona paʻa. e hoʻomaopopo i kēlā pipe.c
hāʻawi mua i nā manawa a pau PPIPE
ke kaheaia sleep()
, pela iho la sleep()
hiki ke hookiia e ka hoailona.
I kēia manawa ua loaʻa iā mākou nā mea āpau e hoʻomaopopo i ka hana 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);
}
Hiki iā ʻoe ke maʻalahi ka heluhelu ʻana i kēia hana mai lalo a luna. Hoʻohana mau ʻia ka lālā "heluhelu a hoʻihoʻi" inā loaʻa kekahi ʻikepili i ka pipeline. I kēia hihia, hoʻohana mākou f_offset
heluhelu, a laila hoʻololi i ka waiwai o ka offset pili.
Ma nā heluhelu aʻe, e nele ka pipeline inā ua hiki i ka offset heluhelu i_size1
ma ka inode. Hoʻihoʻi mākou i ke kūlana i ka 0 a hoʻāʻo e ala i kahi kaʻina hana e makemake e kākau i ka pipeline. Ua ʻike mākou i ka piha ʻana o ka conveyor, writep()
e hiamoe ana ma ip+1
. A i kēia manawa ua nele ka pipeline, hiki iā mākou ke hoʻāla iā ia e hoʻomau i kāna pōʻai kākau.
Inā ʻaʻohe āu mea e heluhelu ai, a laila readp()
hiki ke kau i ka hae IREAD
a hiamoe ma ip+2
. ʻIke mākou i ka mea e hoʻāla iā ia writep()
, ke kākau ʻo ia i kekahi mau ʻikepili i ka pipeline.
Manaʻo ma u
"Hiki iā mākou ke mālama iā lākou e like me nā hana I/O maʻamau e lawe i kahi faila, kahi kūlana, kahi pale i ka hoʻomanaʻo, a helu i ka helu o nā bytes e heluhelu a kākau paha.
/*
* 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;
/* … */
No ka "conservative" blocking, a laila readp()
и writep()
e ālai i ka inode a hoʻopau i kā lākou hana a loaʻa paha kahi hopena (ʻo ia hoʻi, kāhea wakeup
). plock()
и prele()
hana maʻalahi: me ka hoʻohana ʻana i nā kelepona ʻokoʻa sleep
и wakeup
e ʻae iā mākou e ala i kekahi kaʻina hana e pono ai ka laka a mākou i hoʻokuʻu ai:
/*
* 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);
}
}
I ka wā mua ʻaʻole hiki iaʻu ke hoʻomaopopo i ke kumu readp()
ʻaʻole kumu prele(ip)
mamua o ke kahea ana wakeup(ip+1)
. ʻO ka mea mua writep()
kumu i loko o kona pōʻaiapuni, kēia plock(ip)
, ka mea e alakai i ka deadlock ina readp()
ʻaʻole i wehe i kaʻu poloka i kēia manawa, no laila pono e hana pololei ke code. Inā ʻoe e nānā wakeup()
, a laila e maopopo ai he mākaʻikaʻi wale nō ia i ke kaʻina hana hiamoe i mākaukau e hoʻokō, no laila i ka wā e hiki mai ana. sched()
hoʻolana maoli. No laila readp()
mau kumu wakeup()
, wehe i ka laka, hoonoho IREAD
a kelepona sleep(ip+2)
- kēia mau mea ma mua writep()
hoʻomaka hou i ka pōʻaiapuni.
Hoʻopau kēia i ka wehewehe ʻana o nā conveyors i ka paʻi ʻeono. Code maʻalahi, hopena lōʻihi.
Xv6, he kernel like me Unix maʻalahi
No ka hana ʻana i ka kernel
Loaʻa i ke code kahi hoʻokō a maopopo a noʻonoʻo 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()
hoʻonohonoho i ke kūlana o ke koena o ka hoʻokō, e komo pū ana nā hana piperead()
, pipewrite()
и pipeclose()
. Kāhea ʻōnaehana maoli sys_pipe
he wīwī i hoʻokomo ʻia i loko
Linux 0.01
Hiki ke loaʻa ke code kumu Linux 0.01. He mea aʻoaʻo e aʻo i ka hoʻokō ʻana i nā paipu i kāna fs
/pipe.c
. Hoʻohana kēia i ka inode e hōʻike i ka pipeline, akā ua kākau ʻia ka pipeline ponoʻī i ka C hou. ʻO kēia ke ʻano o ka hana 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;
}
Me ka nānā ʻole ʻana i ka wehewehe ʻana, hiki iā ʻoe ke noʻonoʻo pehea e hoʻohana ʻia ai ka helu kuhikuhi inode e nānā i ka hopena o kahi hana kākau. SIGPIPE
. Ma waho aʻe o ka hana byte-by-byte, maʻalahi kēia hana e hoʻohālikelike me nā manaʻo i hōʻike ʻia ma luna. ʻOiai noʻonoʻo sleep_on
/wake_up
ʻaʻole ʻano malihini.
Nā kernel Linux hou, FreeBSD, NetBSD, OpenBSD
Holo wikiwiki au i kekahi mau kernel hou. ʻAʻohe o lākou i hoʻokō i ka disk (ʻaʻole kahaha). Loaʻa iā Linux kona hoʻokō ponoʻī. ʻOiai ʻo nā kernels BSD hou ʻekolu i loaʻa nā hoʻokō e pili ana i ke code i kākau ʻia e John Dyson, i nā makahiki he ʻokoʻa loa lākou mai kekahi i kekahi.
E heluhelu fs
/pipe.c
(ma Linux) a i ʻole sys
/kern
/sys_pipe.c
(ma *BSD), pono ia i ka hoʻolaʻa maoli. ʻO ke code o kēia lā e pili ana i ka hana a me ke kākoʻo no nā hiʻohiʻona e like me vector a me asynchronous I/O. A ʻokoʻa loa nā kikoʻī o ka hoʻokaʻawale hoʻomanaʻo, nā laka a me ka hoʻonohonoho kernel. ʻAʻole kēia ka mea e pono ai nā koleke no kahi papa ʻōnaehana hoʻomaka.
Eia nō naʻe, makemake wau i ka ʻeli ʻana i kekahi mau hiʻohiʻona kahiko (e like me ka hana ʻana SIGPIPE
a hoi mai EPIPE
i ka wā e kākau ai i kahi paipu paʻa) i kēia mau ʻano ʻokoʻa o kēia manawa. ʻAʻole paha au e ʻike i kahi kamepiula PDP-11 i ke ola maoli, akā nui nā mea e aʻo ai mai nā code i kākau ʻia i nā makahiki ma mua o koʻu hānau ʻana.
He ʻatikala i kākau ʻia e Divi Kapoor ma 2011:
Source: www.habr.com