Ichi chinyorwa chinotsanangura kushandiswa kwemapaipi muUnix kernel. Ndakanzwa kuodzwa mwoyo kuti chinyorwa chazvino chine musoro unoti "
Tiri kutaura nezvei?
Mapaipi, "zvichida chinonyanya kukosha muUnix," inotsanangura hunhu hweiyo Unix huzivi hwekubatanidza zvirongwa zvidiki pamwechete, pamwe nechiratidzo chakajairika pamutsetse wekuraira:
$ echo hello | wc -c
6
Kushanda uku kunoenderana neiyo kernel-yakapihwa system call pipe
, iyo inotsanangurwa pamapeji ezvinyorwa
Mapaipi anopa unidirectional chiteshi chekudyidzana kutaurirana. Iyo pombi ine yekupinda (nyora magumo) uye inobuda (verenga kupera). Dhiyabhorosi yakanyorwa kune kuiswa kwepombi inogona kuverengwa pane zvakabuda.
Iyo pombi inogadzirwa uchishandisa kufona
pipe(2)
, iyo inodzosa zvinyorwa zviviri zvefaira: imwe inoreva kupinza kwepombi, yechipiri kune yakabuda.
Iyo yekuteedzera inobuda kubva pamurairo wepamusoro inoratidza kusikwa kwepombi uye kuyerera kwedata kuburikidza nayo kubva kune imwe nzira kuenda kune imwe:
$ 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
Maitiro evabereki anofona pipe()
kuti uwane akakwidzwa faira descriptors. Imwe nzira yemwana inonyora kune imwe mubato, uye imwe nzira inoverenga yakafanana data kubva kune imwe mubato. Iyo goko rinoshandisa dup2 ku "rename" zvinotsanangurwa 3 uye 4 kuti ienderane stdin uye stdout.
Pasina mapaipi, goko raizofanira kunyora mhedzisiro yeimwe nzira kufaira uye kuipfuudza kune imwe nzira yekuverenga iyo data kubva mufaira. Nekuda kweizvozvo, taizopambadza zvimwe zviwanikwa uye disk nzvimbo. Nekudaro, mapaipi akanaka kwete chete nekuti anobvumidza iwe kudzivirira kushandiswa kwemafaira enguva pfupi:
Kana maitiro ari kuedza kuverenga kubva paipi isina chinhu ipapo
read(2)
ichavhara kusvika data yave kuwanikwa. Kana nzira ichiedza kunyora kune yakazara pombi, sakawrite(2)
ichavhara kusvika data yakakwana yaverengwa kubva pombi kuti iite kunyora.
Kufanana nezvinodiwa zvePOSIX, ichi chinhu chakakosha: kunyora kune pombi kusvika PIPE_BUF
mabhayiti (angangoita 512) anofanira kunge ari atomu kuitira kuti maitirwo agone kutaurirana kuburikidza nepombi nenzira iyo mafaira enguva dzose (asingapi zvivimbiso zvakadaro) haakwanise.
Paunenge uchishandisa faira renguva dzose, maitiro anogona kunyora zvese zvawaburitsa kwairi uye ozvipfuudza kune imwe maitiro. Kana kuti maitirwo anogona kushanda nenzira yakanyatsoenderana, uchishandisa nzira yekusaina yekunze (semaphore) kuzivisana kana kunyora kana kuverenga kwapera. Conveyors tiponese kubva kune zvese izvi zvinonetsa.
Tiri kutsvagei?
Ini ndichaitsanangura mumashoko akareruka kuitira kuti zvive nyore kwauri kufungidzira kuti mutakuri anogona kushanda sei. Iwe unozofanirwa kugovera buffer uye imwe nyika mundangariro. Iwe unozoda mabasa ekuwedzera uye kubvisa data kubva mubuffer. Iwe unozoda dzimwe nzira dzekudaidza mabasa panguva yekuverenga nekunyora mashandiro pane zvinotsanangurwa zvefaira. Uye iwe unozoda makiyi kuita iyo yakakosha maitiro atsanangurwa pamusoro.
Ikozvino tagadzirira kubvunzurudza iyo kernel sosi kodhi pasi pemwenje wakajeka kuratidza kana kuramba maitiro edu asina kujeka epfungwa. Asi gara wakagadzirira pane zvisingatarisirwi.
Tiri kutarisa kupi?
Handizive kuti kopi yangu yebhuku rine mukurumbira iripi"
Kufamba-famba nemunzvimbo dzakachengetwa dzeTUHS kwakafanana nekushanyira museum. Tinogona kutarisa nhoroondo yedu yakagovaniswa, uye ndine ruremekedzo kwemakore mazhinji ekuedza kudzoreredza zvese izvi zvishoma zvishoma kubva pamatepi ekare uye akadhinda. Uye ini ndinonyatsoziva nezve izvo zvimedu zvichiri kushaikwa.
Tagutsa kuda kwedu kuziva nezvenhoroondo yekare yezvinotakura zvinhu, tinogona kutarisa kernels dzemazuva ano kuti tizvienzanise.
Nenzira, pipe
ndiyo system yekufona nhamba 42 patafura sysent[]
. Sangana?
Traditional Unix kernels (1970-1974)
Handina kuwana anoronda pipe(2)
kana mukati
TUHS inotaura izvozvo
Unix 1973rd Edition yaive vhezheni yekupedzisira ine kernel yakanyorwa mumutauro wegungano, asiwo yekutanga vhezheni ine mapaipi. Muna XNUMX, basa rakaitwa kuvandudza chinyorwa chechitatu, kernel yakanyorwa patsva muC, uye saka chinyorwa chechina cheUnix chakaonekwa.
Mumwe muverengi akawana scan yegwaro umo Doug McIlroy akakurudzira zano re "kubatanidza zvirongwa senge hose yebindu."
Mubhuku raBrian Kernighan
Unix payakabuda, kunakidzwa kwangu nema coroutines kwakaita kuti ndibvunze munyori weOS, Ken Thompson, kuti abvumire data yakanyorwa kune imwe nzira kuti iende kwete kumudziyo chete, asiwo kuburitsa kune imwe nzira. Ken akasarudza kuti zvaibvira. Nekudaro, se minimalist, aida kuti system yese iite basa rakakosha. Kunyora zvakanangana pakati pemaitiro ibasa guru pane kunyora kune yepakati faira? Pakanga pangove pandakaita chirevo chakananga nezita rinobata "pombi" uye tsananguro yesyntax yekudyidzana pakati pemaitiro izvo Ken akazodaidzira kuti: "Ndichazviita!"
Uye akaita. Mamwe manheru aityisa, Ken akachinja kernel negoko, akagadzirisa zvirongwa zvakati wandei kuti amisikidze mabatiro avakaita mapindiro (anogona kubva papombi), uye akachinja mazita emafaira. Zuva rakatevera, mapaipi akatanga kushandiswa zvakanyanya mukushandiswa. Pakazopera vhiki, vanyori vakanga vava kuashandisa kutumira magwaro kubva kumagadzirirwo emashoko kuenda kumudhindi. Mushure mechinguva chidiki, Ken akatsiva iyo yekutanga API uye syntax yekuputira kushandiswa kwepombi nemakonisheni akachenesa, ayo ave achishandiswa kubva ipapo.
Nehurombo, iyo kodhi kodhi yechitatu edition Unix kernel yarasika. Uye kunyangwe isu tine kernel sosi kodhi yakanyorwa muC
Tine zvinyorwa zvinyorwa zve pipe(2)
kubva pane zvese zvaburitswa, saka unogona kutanga nekutsvaga zvinyorwa pipe(2)
yakanyorwa mumutauro wegungano uye inongodzosera faira rimwe chete rinotsanangura, asi rinotopa iro rinotarisirwa basa rekutanga:
System call pipe inogadzira nzira yekupinza/inoburitsa inonzi pipeline. Iyo yakadzoserwa faira descriptor inogona kushandiswa kuverenga nekunyora mashandiro. Kana chimwe chinhu chichinyorwa kune pombi, inosvika 504 bytes yedata inovharwa, mushure mezvo maitiro ekunyora anomiswa. Paunenge uchiverenga kubva papombi, iyo buffer data inotorwa.
Pakazosvika gore rakatevera kernel yakanga yanyorwazve muC, uye pipe(fildes)
Β»:
System call pipe inogadzira nzira yekupinza/inoburitsa inonzi pipeline. Iyo yakadzoserwa faira tsananguro inogona kushandiswa mukuverenga nekunyora mashandiro. Kana chimwe chinhu chichinyorwa kune pombi, mubato wakadzoserwa mu r1 (resp. fildes[1]) unoshandiswa, wakavharirwa ku4096 bytes yedata, mushure mezvo kunyora kunomiswa. Paunenge uchiverenga kubva pombi, mubato wakadzokera ku r0 (resp. fildes[0]) unotora data.
Zvinofungidzirwa kuti kana pombi yatsanangurwa, maviri (kana kupfuura) nzira dzekutaurirana (dzakagadzirwa nefoni dzinotevera Fork) ichaendesa data kubva pombi uchishandisa mafoni verenga ΠΈ nyora.
Iyo shell ine syntax yekutsanangura mutsara mutsara wemaitiro akabatanidzwa nepombi.
Mafoni ekuverenga kubva papombi isina chinhu (isina data yakavharwa) ine mugumo mumwe chete (zvese zvinyorwa zvefaira zvekunyora zvakavharwa) dzorera "kupera kwefaira". Mafoni ekunyora mumamiriro ezvinhu akafanana anofuratirwa.
Earliest
Gwaro rechitanhatu reUnix (1975)
Ngatitange kuverenga Unix source code
Kwemakore akawanda bhuku racho shumba ndiro chete gwaro paUnix kernel inowanikwa kunze kweBell Labs. Kunyange zvazvo rezinesi rechitanhatu raibvumira vadzidzisi kushandisa kodhi yaro, rezenisi reshanduro yechinomwe rakanga risingabatanidzi mukana uyu, saka bhuku racho rakaparadzirwa semakopi akanyorwa zvisiri pamutemo.
Nhasi unogona kutenga kudhindwazve kwebhuku, kavha iyo inoratidza vadzidzi pamushini wekukopa. Uye nekuda kweWarren Toomey (uyo akatanga chirongwa cheTUHS) unogona kudhawunirodha
Anopfuura makore gumi nemashanu apfuura, ndakataipa kopi yekodhi kodhi yakapihwa mukati shumba, nokuti ndakanga ndisingadi kunaka kwekopi yangu kubva kune nhamba isingazivikanwi yemamwe makopi. TUHS yanga isati yavepo uye ini ndakanga ndisingakwanise kuwana zvekare zvinyorwa. Asi muna 1988, ndakawana tepi yekare ye9-track yaive ne backup kubva pakombuta yePDP11. Zvakanga zvakaoma kutaura kana yaishanda, asi pakanga paine intact / usr/src/ muti umo mafaera mazhinji aive akanyorwa negore 1979, iro rakatotaridzika rekare. Yakanga iri chinyorwa chechinomwe kana chirevo chayo chePWB, sezvandaitenda.
Ndakatora iyo yakawana sehwaro uye nemaoko ndakagadzirisa masosi kune yechitanhatu edition. Imwe kodhi yakaramba yakafanana, asi imwe yaifanirwa kugadziridzwa zvishoma, ichichinja yemazuva ano += tokeni kune yechinyakare =+. Zvimwe zvinhu zvakangodzimwa, uye zvimwe zvaifanira kunyorwazve, asi kwete zvakanyanya.
Uye nhasi tinogona kuverenga online paTUHS iyo kodhi kodhi yechitanhatu edition kubva
Nenzira, pakutanga kutarisa, chinhu chikuru cheC-code nguva isati yasvika yeKernighan naRitchie ndiyo yayo. pfupi. Haisi kazhinji kuti ini ndinokwanisa kuisa zvidimbu zvekodhi pasina kurongeka kwakawanda kuti ikwane nzvimbo yakamanikana yekuratidzira pane yangu saiti.
Pakutanga
/*
* 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
Saizi yebhafa haina kushanduka kubva pashanduro yechina. Asi pano tinoona, pasina chero zvinyorwa zveveruzhinji, kuti mapaipi akamboshandisa mafaera sekuchengetedza kuchengetedza!
Kana ari LARG mafaera, anowirirana ne
Heino chaiyo system call 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;
}
Mhinduro yacho inotsanangura zvakajeka zviri kuitika pano. Asi kunzwisisa kodhi hakusi nyore, chikamu nekuda kwenzira "R0
ΠΈ R1
system call parameters uye kudzoka kukosha kunopfuudzwa.
Ngatiedze ne
pipe()
anofanira kuburikidza R0
ΠΈ R1
dzosa nhamba dzetsananguro dzefaira dzekuverenga nekunyora. falloc()
inodzosera chinongedzo kune iyo faira chimiro, asi zvakare "inodzoka" kuburikidza u.u_ar0[R0]
uye faira descriptor. Ndiko kuti, kodhi inochengetedza mukati r
faira descriptor yekuverenga uye inopa tsananguro yefaira yekunyora zvakananga kubva u.u_ar0[R0]
mushure mekufona kwechipiri falloc()
.
Flag FPIPE
, iyo yatinoisa pakugadzira pombi, inodzora maitiro ebasa racho
/*
* 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);
}
/* β¦ */
}
Zvadaro basa readp()
Π² pipe.c
inoverenga data kubva pombi. Asi zviri nani kuronda kuitisa kutanga kubva writep()
. Zvekare, iyo kodhi yawedzera kuomarara nekuda kwezvibvumirano zvekupfuura nharo, asi mamwe madeti anogona kusiiwa.
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;
}
Tinoda kunyora mabhaiti kune pombi yekupinda u.u_count
. Kutanga isu tinoda kukiya iyo inode (ona pazasi plock
/prele
).
Zvadaro tinotarisa inode reference counter. Chero bedzi migumo yese yepombi ichiramba yakavhurika, counter inofanira kuenzana ne 2. Tinobata imwe link (kubva rp->f_inode
), saka kana counter iri pasi pe2, inofanira kureva kuti kuverenga kwakavhara kupera kwayo kwepombi. Mune mamwe mazwi, tiri kuedza kunyorera pombi yakavharwa, uye ichi chikanganiso. Kekutanga kukanganisa kodhi EPIPE
uye chiratidzo SIGPIPE
yakabuda muchikamu chechitanhatu cheUnix.
Asi kunyange kana conveyor yakazaruka, inogona kunge yakazara. Muchiitiko ichi, tinosunungura kuvhara uye tinoenda kunorara mune tariro yokuti imwe nzira ichaverenga kubva pombi uye kusunungura nzvimbo yakakwana mairi. Tamuka, tinodzokera pakutanga, sungirira kukiya zvakare uye wotanga kutenderera kutsva kwekurekodha.
Kana pane nzvimbo yakakwana yemahara mupombi, saka tinonyora data kwairi tichishandisa i_size1
inode (kana pombi isina chinhu, inogona kuenzana ne0) inoratidza kupera kwe data iyo yatove nayo. Kana paine nzvimbo yekurekodha yakakwana, tinogona kuzadza pombi kubva i_size1
up to PIPESIZ
. Zvadaro tinosunungura kuvhara uye edza kumutsa chero maitiro akamirira kuverenga kubva pombi. Tinodzokera kumashure kuti tione kana takakwanisa kunyora mabhaiti akawanda sezvataida. Kana ikatadza, saka tinotanga kutenderera kutsva kwekurekodha.
Kazhinji parameter i_mode
inode inoshandiswa kuchengetedza mvumo r
, w
ΠΈ x
. Asi panyaya yemapaipi, tinoratidza kuti mamwe maitiro akamirira kunyora kana kuverenga uchishandisa mabits IREAD
ΠΈ IWRITE
zvichiteerana. Iyo nzira inoisa mureza uye inofona sleep()
, uye zvinotarisirwa kuti imwe nzira mune ramangwana ichakonzera wakeup()
.
Mashiripiti chaiwo anoitika mukati sleep()
ΠΈ wakeup()
. Zvinoitwa mukati
/*
* 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) /* β¦ */
Nzira inokonzera sleep()
kune imwe nzira, inogona kuzomutswa neimwe nzira, inozokonzera wakeup()
kune imwe chiteshi. writep()
ΠΈ readp()
kurongedza zviito zvavo kuburikidza nemafoni maviri akadai. cherechedza kuti pipe.c
nguva dzose inopa pakutanga PPIPE
kana adanwa sleep()
, saka ndizvozvo sleep()
inogona kuvhiringwa nechiratidzo.
Iye zvino tine zvose kuti tinzwisise basa racho 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);
}
Unogona kuwana zviri nyore kuverenga basa iri kubva pasi kusvika kumusoro. Iro "kuverenga nekudzoka" bazi rinowanzo shandiswa kana paine imwe data mupombi. Muchiitiko ichi, tinoshandisa f_offset
kuverenga, uye wobva wavandudza kukosha kweiyo inoenderana offset.
Pakuverenga kunotevera, pombi ichange isina chinhu kana iyo yekuverenga offset yasvika i_size1
pa inode. Isu tinogadzirisa nzvimbo yacho ku0 uye edza kumutsa chero maitiro anoda kunyora kune pombi. Tinoziva kuti kana conveyor yazara, writep()
achakotsira ip+1
. Uye zvino sezvo pombi isina chinhu, tinogona kuimutsa kuti itangezve kutenderera kwayo kwekunyora.
Kana usina chekuverenga, saka readp()
anogona kuseta mureza IREAD
ndokuvata ip+2
. Tinoziva zvichamumutsa writep()
, painonyora imwe data kune pombi.
Comments to u
"Tinogona kuvabata senge zvakajairika I / O mabasa anotora faira, chinzvimbo, buffer mundangariro, uye kuverenga nhamba yemabhaiti kuverenga kana kunyora.
/*
* 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;
/* β¦ */
Kana iri "inochengetedza" kuvharira, saka readp()
ΠΈ writep()
vhara iyo inode kusvika vapedza basa ravo kana kugamuchira mhedzisiro (kureva, kufona wakeup
). plock()
ΠΈ prele()
shanda zviri nyore: kushandisa akasiyana seti yekufona sleep
ΠΈ wakeup
tibvumire kumutsa chero maitiro anoda kukiyiwa kwatichangobva kuburitsa:
/*
* 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);
}
}
Pakutanga ndakatadza kunzwisisa chikonzero nei readp()
haina kukonzera prele(ip)
tisati tafona wakeup(ip+1)
. Chinhu chekutanga ndechekuti writep()
zvinokonzera mukutenderera kwayo, izvi plock(ip)
, izvo zvinotungamira kune deadlock kana readp()
handisati ndabvisa block yangu, saka neimwe nzira kodhi inofanira kushanda nemazvo. Kana iwe ukatarisa wakeup()
, zvino zvinova pachena kuti inongoratidzira nzira yekurara seyakagadzirira kuita, kuitira kuti mune ramangwana sched()
zvaitanga chaizvo. Saka readp()
chinokonzera wakeup()
, inobvisa kukiya, inoisa IREAD
uye kufona sleep(ip+2)
- zvese izvi zvisati zvaitika writep()
inotangazve kutenderera.
Izvi zvinopedzisa tsananguro yemaconveyors muchikamu chechitanhatu. Nyore kodhi, mhedzisiro inosvika kure.
Xv6, iri nyore Unix-yakafanana kernel
Kugadzira kernel
Iyo kodhi ine yakajeka uye inofungisisa kuita 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()
inogadzirisa mamiriro ezvimwe zvekushandiswa, izvo zvinosanganisira mabasa piperead()
, pipewrite()
ΠΈ pipeclose()
. Actual system call sys_pipe
iri wrapper inoshandiswa mukati
Linux 0.01
Linux 0.01 source code inogona kuwanikwa. Zvichava kudzidzisa kudzidza kushandiswa kwepombi mune yake fs
/pipe.c
. Izvi zvinoshandisa inode kumiririra pombi, asi pombi pachayo yakanyorwa nemazuva ano C. Kana iwe wakashanda nzira yako kuburikidza neXNUMXth edition code, hauzove nedambudziko pano. Izvi ndizvo zvinoita basa racho 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;
}
Pasina kana kutarisa kune tsananguro yechimiro, unogona kuona kuti inode reference count inoshandiswa sei kutarisa kana basa rekunyora rinoguma SIGPIPE
. Pamusoro pekushanda byte-by-byte, basa iri riri nyore kuenzanisa nemazano anotsanangurwa pamusoro. Kunyange pfungwa sleep_on
/wake_up
hazviratidzike semutorwa.
Mazuva ano Linux kernels, FreeBSD, NetBSD, OpenBSD
Ndakabva ndamhanya nemu tsanga dzemazuvano. Hapana kana mumwe wavo ane dhisiki kuita zvakare (hazvishamise). Linux ine kwayo kuita kwayo. Kunyangwe iwo matatu emazuva ano BSD kernels aine mashandisirwo akavakirwa pakodhi yakanyorwa naJohn Dyson, nekufamba kwemakore vakave vakasiyana zvakanyanya kubva kune mumwe nemumwe.
Kuverenga fs
/pipe.c
(paLinux) kana sys
/kern
/sys_pipe.c
(pa * BSD), zvinoda kuzvipira chaiko. Kodhi yanhasi ndeyekuita uye kutsigirwa kwezvinhu zvakaita sevector uye asynchronous I/O. Uye ruzivo rwekugoverwa kwendangariro, makiyi uye kernel kumisikidzwa zvese zvinosiyana zvakanyanya. Izvi hazvisi izvo izvo makoreji anoda kune yekutanga masisitimu ekushandisa kosi.
Zvakadaro, ndaifarira kuchera mamwe mapatani ekare (sekugadzira SIGPIPE
uye kudzoka EPIPE
pakunyorera pombi yakavharwa) mune idzi kernels dzakasiyana dzemazuva ano. Ini handifi ndakamboona PDP-11 komputa muhupenyu chaihwo, asi pachine zvakawanda zvekudzidza kubva kukodhi yakanyorwa makore ndisati ndazvarwa.
Chinyorwa chakanyorwa naDivi Kapoor muna 2011:
Source: www.habr.com