Atik sa a dekri aplikasyon tiyo nan nwayo Unix la. Mwen te yon ti jan wont ke yon dènye atik ki gen tit "
De kisa nap pale?
Pipelines yo se "pwobableman envansyon ki pi enpòtan nan Unix" - yon karakteristik defini nan filozofi ki kache nan Unix nan mete ansanm ti pwogram yo, ak eslogan liy kòmand yo abitye:
$ echo hello | wc -c
6
Fonksyonalite sa a depann de apèl sistèm kenel bay la pipe
, ki dekri nan paj dokiman yo
Pipelines bay yon kanal yon sèl pou kominikasyon ant pwosesis. Tiyo a gen yon opinyon (ekri fen) ak yon pwodiksyon (li fen). Done ekri nan opinyon tiyo a ka li nan pwodiksyon an.
Se tiyo a kreye lè w rele
pipe(2)
, ki retounen de deskriptè dosye: youn refere a opinyon tiyo a, dezyèm lan nan pwodiksyon an.
Pwodiksyon tras ki soti nan kòmandman ki anwo a montre kreyasyon yon tiyo ak koule nan done atravè li soti nan yon pwosesis nan yon lòt:
$ 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
Pwosesis paran an rele pipe()
pou jwenn deskriptè dosye ki tache. Yon pwosesis timoun ekri nan yon deskriptè epi yon lòt pwosesis li menm done ki soti nan yon lòt deskriptè. Koki a "chanje non" deskriptè 2 ak 3 ak dup4 pou matche stdin ak stdout.
San tiyo, koki a ta dwe ekri pwodiksyon yon pwosesis nan yon dosye epi tiyo li nan yon lòt pwosesis pou li done ki soti nan dosye a. Kòm yon rezilta, nou ta gaspiye plis resous ak espas disk. Sepandan, tiyo yo bon pou plis pase jis evite dosye tanporè:
Si yon pwosesis eseye li nan yon tiyo vid, lè sa a
read(2)
pral bloke jiskaske done yo disponib. Si yon pwosesis eseye ekri nan yon tiyo plen, lè sa awrite(2)
pral bloke jiskaske ase done yo te li nan tiyo a ranpli ekri a.
Menm jan ak egzijans POSIX, sa a se yon pwopriyete enpòtan: ekri nan tiyo a jiska PIPE_BUF
bytes (omwen 512) dwe atomik pou pwosesis yo ka kominike youn ak lòt atravè tiyo a nan yon fason ke dosye nòmal (ki pa bay garanti sa yo) pa kapab.
Avèk yon dosye regilye, yon pwosesis ka ekri tout pwodiksyon li yo nan li epi pase li nan yon lòt pwosesis. Oswa pwosesis yo ka opere nan yon mòd paralèl difisil, lè l sèvi avèk yon mekanis siyal ekstèn (tankou yon semafò) enfòme youn ak lòt sou fini an nan yon ekri oswa li. Transporteurs sove nou anba tout traka sa yo.
Kisa nap chache?
Mwen pral eksplike sou dwèt mwen pou fè li pi fasil pou ou imajine ki jan yon CONVEYOR ka travay. Ou pral bezwen asiyen yon tanpon ak kèk eta nan memwa. W ap bezwen fonksyon pou ajoute epi retire done nan tanpon an. Ou pral bezwen kèk etablisman pou rele fonksyon pandan operasyon lekti ak ekri sou deskriptè dosye yo. Ak kadna yo bezwen aplike konpòtman espesyal ki dekri pi wo a.
Kounye a nou pare pou n entèwoje kòd sous nwayo a anba limyè klere pou konfime oswa demanti modèl mantal vag nou an. Men, toujou pare pou inatandi.
Kote nap chache?
Mwen pa konnen ki kote kopi mwen an nan liv la pi popilè manti.
Pèdi nan achiv TUHS yo se tankou vizite yon mize. Nou ka gade istwa nou pataje epi mwen gen respè pou ane efò yo te fè pou rekipere tout materyèl sa a ti pa ti kras nan ansyen kasèt ak enprime. Apre sa, mwen byen konsyan de fragman sa yo ki toujou manke.
Èske w gen satisfè kiryozite nou sou istwa a ansyen nan tiyo, nou ka gade nan nwayo modèn pou konparezon.
By wout la, pipe
se nimewo apèl sistèm 42 nan tablo a sysent[]
. Konyensidans?
Nwayo tradisyonèl Unix (1970–1974)
Mwen pa jwenn okenn tras pipe(2)
ni nan
TUHS reklamasyon sa
Twazyèm edisyon Unix te dènye vèsyon an ak yon nwayo ekri nan asanblaj, men tou, premye vèsyon an ak tiyo. Pandan lane 1973, travay te fèt pou amelyore twazyèm edisyon an, nwayo a te reekri an C, e konsa katriyèm edisyon Unix te fèt.
Yon lektè te jwenn yon eskanè nan yon dokiman kote Doug McIlroy te pwopoze lide pou "konekte pwogram tankou yon kawotchou jaden."
Nan liv Brian Kernighan a
Lè Unix te parèt, pasyon mwen pou coroutines te fè m mande otè OS la, Ken Thompson, pou pèmèt done ekri nan kèk pwosesis ale non sèlman nan aparèy la, men tou nan sòti nan yon lòt pwosesis. Ken te panse li te posib. Sepandan, kòm yon minimalist, li te vle chak karakteristik sistèm yo jwe yon wòl enpòtan. Èske ekri dirèk ant pwosesis reyèlman yon gwo avantaj sou ekri nan yon dosye entèmedyè? Epi sèlman lè mwen te fè yon pwopozisyon espesifik ak non atiran "pipeline" ak yon deskripsyon sentaks nan entèraksyon an nan pwosesis, Ken finalman eksklame: "Mwen pral fè li!".
Epi li te fè. Yon aswè fatal, Ken te chanje nwayo a ak kokiy, li te ranje plizyè pwogram estanda pou estandadize fason yo aksepte opinyon (ki ta ka soti nan yon tiyo), epi li chanje non fichye yo. Nan denmen, tiyo yo te trè lajman itilize nan aplikasyon yo. Nan fen semèn nan, sekretè yo te itilize yo pou voye dokiman ki soti nan prosesè tèks nan enprimant lan. Yon ti jan pita, Ken te ranplase API orijinal la ak sentaks pou vlope itilizasyon tiyo ak konvansyon ki pi pwòp ki te itilize depi lè sa a.
Malerezman, kòd sous la pou twazyèm edisyon Kernel Unix la te pèdi. Ak byenke nou gen kòd sous nwayo a ekri nan C
Nou gen tèks dokimantasyon pou pipe(2)
soti nan tou de degaje yo, kidonk, ou ka kòmanse pa rechèch dokiman an pipe(2)
ekri nan asanblaj epi li retounen sèlman yon deskriptè dosye, men li deja bay fonksyonalite debaz yo espere:
Sistèm apèl tiyo kreye yon mekanis I/O ki rele yon tiyo. Yo ka itilize deskriptè fichye a retounen pou operasyon lekti ak ekri. Lè yon bagay ekri nan tiyo a, li tampon jiska 504 bytes nan done, apre sa pwosesis ekri a sispann. Lè w ap li nan tiyo a, yo pran done tanpon yo.
Nan ane annapre a, nwayo a te reekri nan C, ak pipe(fildes)
'
Sistèm apèl tiyo kreye yon mekanis I/O ki rele yon tiyo. Deskriptè dosye yo retounen yo ka itilize nan operasyon lekti ak ekri. Lè yo ekri yon bagay nan tiyo a, deskriptè ki te retounen nan r1 (resp. fildes[1]) yo itilize, tanpon jiska 4096 octets done, apre sa pwosesis ekri a sispann. Lè li nan tiyo a, deskriptè a tounen nan r0 (resp. fildes[0]) pran done yo.
Li sipoze ke yon fwa yo te defini yon tiyo, de (oswa plis) pwosesis entèraksyon (kreye pa envokasyon ki vin apre yo). fouchèt) pral pase done ki soti nan tiyo a lè l sèvi avèk apèl yo li и ekri.
Koki a gen yon sentaks pou defini yon etalaj lineyè pwosesis ki konekte atravè yon tiyo.
Apèl pou li nan yon tiyo vid (ki pa gen done tanpon) ki gen yon sèl fen (tout deskriptè fichye ekri fèmen) retounen "fen fichye". Ekri apèl nan yon sitiyasyon ki sanble yo inyore.
Pi bonè
Sizyèm Edisyon Unix (1975)
Kòmanse li kòd sous Unix
Pou anpil ane liv la Lyon se te sèl dokiman sou nwayo Unix ki disponib deyò Bell Labs. Malgre ke lisans sizyèm edisyon an te pèmèt pwofesè yo sèvi ak kòd sous li a, lisans setyèm edisyon an eskli posibilite sa a, kidonk liv la te distribye nan kopi ilegal tape.
Jodi a ou ka achte yon kopi reimprime nan liv la, kouvèti a ki dekri elèv yo nan fotokopi a. Ak gras a Warren Toomey (ki te kòmanse pwojè a TUHS), ou ka telechaje
Plis pase 15 ane de sa, mwen tape yon kopi kòd sous yo bay nan Lyonpaske mwen pa t renmen kalite kopi mwen an soti nan yon kantite lòt kopi enkoni. TUHS pa t egziste ankò, e mwen pa t gen aksè a ansyen sous yo. Men an 1988 mwen te jwenn yon vye kasèt ak 9 tracks ki te gen yon backup nan yon òdinatè PDP11. Li te difisil pou konnen si li te travay, men te gen yon pyebwa entak /usr/src/ kote pifò nan fichye yo te make 1979, ki menm lè sa a te sanble ansyen. Se te setyèm edisyon an, oswa yon derive PWB, mwen te panse.
Mwen te pran jwenn la kòm yon baz ak manyèlman edited sous yo nan eta a nan sizyèm edisyon an. Yon pati nan kòd la rete menm jan an, yon pati te dwe yon ti kras modifye, chanje siy modèn la += nan demode =+ la. Yon bagay te tou senpleman efase, ak yon bagay te dwe konplètman reekri, men se pa twòp.
Ak jodi a nou ka li sou entènèt nan TUHS kòd sous la nan sizyèm edisyon an
By wout la, nan premye gade, karakteristik prensipal la nan C-kòd la anvan peryòd Kernighan ak Ritchie se li yo. konsizyon. Li pa souvan ke mwen kapab mete snippets nan kòd san koreksyon vaste anfòm yon zòn ekspozisyon relativman etwat sou sit mwen an.
Nan kòmansman an
/*
* 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
Gwosè tanpon an pa chanje depi katriyèm edisyon an. Men, isit la nou wè, san okenn dokiman piblik, ke tiyo yon fwa te itilize dosye kòm depo depo!
Kòm pou fichye LARG, yo koresponn ak
Isit la se apèl sistèm reyèl la 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;
}
Kòmantè a dekri byen klè sa k ap pase isit la. Men, li pa fasil pou konprann kòd la, an pati akòz ki jan "R0
и R1
paramèt apèl sistèm ak valè retounen yo pase.
Ann eseye ak
pipe()
akòz R0
и R1
retounen nimewo deskriptè dosye pou lekti ak ekri. falloc()
retounen yon konsèy nan yon estrikti dosye, men tou, "retounen" atravè u.u_ar0[R0]
ak yon deskriptè dosye. Sa vle di, kòd la estoke nan r
deskriptè dosye pou lekti epi bay yon deskriptè pou ekri dirèkteman nan u.u_ar0[R0]
apre dezyèm apèl falloc()
.
Drapo FPIPE
, ki nou mete lè kreye tiyo a, kontwole konpòtman an nan fonksyon an
/*
* 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);
}
/* … */
}
Lè sa a, fonksyon an readp()
в pipe.c
li done ki soti nan tiyo a. Men, li se pi bon trase aplikasyon an kòmanse nan writep()
. Yon fwa ankò, kòd la te vin pi konplike akòz nati a nan konvansyon an pase agiman, men kèk detay ka omisyon.
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;
}
Nou vle ekri octets nan opinyon tiyo a u.u_count
. Premyèman, nou bezwen fèmen inode la (gade anba a plock
/prele
).
Lè sa a, nou tcheke konte referans inode. Osi lontan ke tou de bout tiyo a rete louvri, kontwa a ta dwe 2. Nou kenbe sou yon sèl lyen (ki soti nan rp->f_inode
), Se konsa, si kontwa a se mwens pase 2, Lè sa a, sa ta dwe vle di ke pwosesis la lekti te fèmen fen tiyo li yo. Nan lòt mo, nou ap eseye ekri nan yon tiyo fèmen, ki se yon erè. Premye kòd erè EPIPE
ak siyal SIGPIPE
parèt nan sizyèm edisyon Unix.
Men, menm si CONVEYOR la louvri, li ka plen. Nan ka sa a, nou lage seri a epi ale nan dòmi nan espwa ke yon lòt pwosesis pral li nan tiyo a ak libere ase espas nan li. Lè nou reveye, nou retounen nan kòmansman an, rakwoche seri a ankò epi kòmanse yon nouvo sik ekri.
Si gen ase espas gratis nan tiyo a, Lè sa a, nou ekri done sou li lè l sèvi avèk i_size1
inode'a a (ak yon tiyo vid ka egal a 0) pwen nan fen done yo ke li deja genyen. Si gen ase espas pou ekri, nou ka ranpli tiyo a soti i_size1
до PIPESIZ
. Lè sa a, nou lage seri a epi eseye reveye nenpòt pwosesis ki ap tann li nan tiyo a. Nou tounen nan kòmansman an pou wè si nou te rive ekri otan octets ke nou bezwen. Si ou pa, Lè sa a, nou kòmanse yon nouvo sik anrejistreman.
Anjeneral paramèt i_mode
inode yo itilize pou estoke otorizasyon yo r
, w
и x
. Men, nan ka a nan tiyo, nou siyal ke kèk pwosesis ap tann pou yon ekri oswa li lè l sèvi avèk Bits IREAD
и IWRITE
respektivman. Pwosesis la mete drapo a ak apèl sleep()
, epi li espere ke nan tan kap vini an kèk lòt pwosesis pral rele wakeup()
.
Vrè maji a rive nan sleep()
и wakeup()
. Yo aplike nan
/*
* 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) /* … */
Pwosesis la ki rele sleep()
pou yon kanal patikilye, ka pita dwe reveye pa yon lòt pwosesis, ki pral rele wakeup()
pou menm chanèl la. writep()
и readp()
kowòdone aksyon yo atravè apèl pè sa yo. sonje ke pipe.c
toujou bay priyorite PPIPE
lè yo rele sleep()
, se konsa tout sleep()
ka entèwonp pa yon siyal.
Koulye a, nou gen tout bagay yo konprann fonksyon an 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);
}
Ou ta ka jwenn li pi fasil pou li fonksyon sa a anba nan tèt. Se branch "li epi retounen" anjeneral yo itilize lè gen kèk done nan tiyo a. Nan ka sa a, nou itilize f_offset
li, epi mete ajou valè konpanse ki koresponn lan.
Nan lekti ki vin apre yo, tiyo a pral vid si konpanse lekti a rive i_size1
nan inode la. Nou reset pozisyon an 0 epi eseye reveye nenpòt pwosesis ki vle ekri nan tiyo a. Nou konnen ke lè transporteur a plen, writep()
tonbe nan dòmi sou ip+1
. Epi kounye a ke tiyo a vid, nou ka reveye li pou rekòmanse sik ekri li yo.
Si pa gen anyen pou li, lè sa a readp()
ka mete yon drapo IREAD
epi tonbe nan dòmi sou ip+2
. Nou konnen sa ki pral reveye l writep()
lè li ekri kèk done nan tiyo a.
Kòmantè sou u
» nou ka trete yo tankou fonksyon I/O regilye ki pran yon dosye, yon pozisyon, yon tanpon nan memwa, epi konte kantite byte pou li oswa ekri.
/*
* 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;
/* … */
Kòm pou "konsèvatif" bloke, lè sa a readp()
и writep()
fèmen inodes jiskaske yo fini oswa jwenn yon rezilta (sa vle di rele wakeup
). plock()
и prele()
travay tou senpleman: lè l sèvi avèk yon seri diferan nan apèl sleep
и wakeup
pèmèt nou reveye nenpòt pwosesis ki bezwen kadna nou sot lage a:
/*
* 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);
}
}
Okòmansman mwen pa t 'kapab konprann poukisa readp()
pa lakòz prele(ip)
anvan apèl la wakeup(ip+1)
. Premye bagay writep()
apèl nan bouk li yo, sa a plock(ip)
, ki rezilta nan yon enpas si readp()
poko retire blòk li, kidonk kòd la dwe yon jan kanmenm travay kòrèkteman. Si ou gade wakeup()
, li vin klè ke li sèlman make pwosesis la dòmi kòm pare pou ekzekisyon, se konsa ke nan tan kap vini an sched()
vrèman te lanse li. Se konsa readp()
lakòz wakeup()
, déblotché, mete IREAD
ak apèl sleep(ip+2)
- tout bagay sa yo anvan writep()
rekòmanse sik la.
Sa a konplete deskripsyon tiyo nan sizyèm edisyon an. Senp kòd, enplikasyon byen lwen.
Xv6, yon nwayo senp tankou Unix
Pou kreye yon nwayo
Kòd la gen yon aplikasyon klè ak reflechi 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()
fikse eta a nan tout rès aplikasyon an, ki gen ladan fonksyon piperead()
, pipewrite()
и pipeclose()
. Rele sistèm aktyèl la sys_pipe
se yon wrapper aplike nan
Linux 0.01
Ou ka jwenn kòd sous la pou Linux 0.01. Li pral édikatif yo etidye aplikasyon an nan tuyaux nan l 'yo fs
/pipe.c
. Isit la, yo itilize yon inode pou reprezante tiyo a, men tiyo a li menm ekri nan C modèn. Si ou te rache wout ou nan kòd la sizyèm edisyon, ou pa pral gen okenn pwoblèm isit la. Sa a se sa fonksyon an sanble 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;
}
Menm san gade nan definisyon estrikti yo, ou ka konnen ki jan konte referans inode yo itilize pou tcheke si yon operasyon ekri rezilta nan. SIGPIPE
. Anplis travay byte-by-byte, fonksyon sa a fasil pou konpare ak lide ki anwo yo. Menm lojik sleep_on
/wake_up
pa sanble etranje konsa.
Modèn Linux Kernels, FreeBSD, NetBSD, OpenBSD
Mwen byen vit ale sou kèk nwayo modèn. Okenn nan yo pa deja gen yon aplikasyon ki baze sou disk (pa etone). Linux gen pwòp aplikasyon li. Ak byenke twa nwayo BSD modèn yo gen enplemantasyon ki baze sou kòd ki te ekri pa John Dyson, pandan ane yo yo te vin twò diferan youn ak lòt.
Pou li fs
/pipe.c
(sou Linux) oswa sys
/kern
/sys_pipe.c
(sou *BSD), li pran devouman reyèl. Pèfòmans ak sipò pou karakteristik tankou vektè ak I/O asynchrone yo enpòtan nan kòd jodi a. Ak detay yo sou alokasyon memwa, kadna, ak konfigirasyon nwayo tout varye anpil. Sa a se pa sa inivèsite yo bezwen pou yon kou entwodiksyon sou sistèm opere.
Nan nenpòt ka, li te enteresan pou m 'detire kèk modèl fin vye granmoun (pa egzanp, génération SIGPIPE
epi retounen EPIPE
lè ekri nan yon tiyo fèmen) nan tout sa yo, konsa diferan, nwayo modèn. Mwen pral pwobableman pa janm wè yon òdinatè PDP-11 ap viv, men gen toujou anpil bagay yo aprann nan kòd la ki te ekri kèk ane anvan mwen te fèt.
Ekri pa Divi Kapoor nan 2011, atik la "
Sous: www.habr.com