Kab lus no piav qhia txog kev siv cov kav dej hauv Unix kernel. Kuv poob siab me ntsis tias ib tsab xov xwm tsis ntev los no hu ua "
Peb tham txog dab tsi?
Pipelines, "tej zaum qhov kev tsim kho tseem ceeb tshaj plaws hauv Unix," yog tus cwj pwm ntawm lub hauv paus Unix lub tswv yim ntawm kev sib txuas cov kev pab cuam me me ua ke, nrog rau cov cim paub txog ntawm kab hais kom ua:
$ echo hello | wc -c
6
Qhov kev ua haujlwm no nyob ntawm qhov kev hu xov tooj rau ntsiav pipe
, uas tau piav qhia ntawm nplooj ntawv cov ntaub ntawv
Cov kav dej muab ib txoj kab ncaj nraim rau kev sib txuas lus. Lub raj xa dej muaj ib qho kev tawm tswv yim (sau kawg) thiab cov zis (nyeem kawg). Cov ntaub ntawv sau rau cov tswv yim ntawm cov raj xa dej tuaj yeem nyeem tau ntawm qhov tso zis.
Lub raj xa dej yog tsim los ntawm kev hu
pipe(2)
, uas xa rov qab ob daim ntawv piav qhia: ib qho xa mus rau cov tswv yim ntawm cov raj xa dej, qhov thib ob rau cov zis.
Cov kab tawm los ntawm cov lus txib saum toj no qhia txog kev tsim cov raj xa dej thiab cov ntaub ntawv ntws los ntawm nws los ntawm ib txheej txheem mus rau lwm qhov:
$ 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
Cov txheej txheem niam txiv hu pipe()
kom tau mounted file descriptors. Ib tug me nyuam txheej txheem sau rau ib tug kov, thiab lwm tus txheej txheem nyeem tib cov ntaub ntawv los ntawm lwm tus kov. Lub plhaub siv dup2 rau "rename" descriptors 3 thiab 4 kom phim stdin thiab stdout.
Yog tsis muaj cov kav dej, lub plhaub yuav tsum tau sau cov txiaj ntsig ntawm ib txheej txheem rau ib cov ntaub ntawv thiab dhau mus rau lwm cov txheej txheem los nyeem cov ntaub ntawv los ntawm cov ntaub ntawv. Yog li ntawd, peb yuav nkim ntau cov peev txheej thiab qhov chaw disk. Txawm li cas los xij, cov kav dej zoo tsis yog vim lawv tso cai rau koj kom tsis txhob siv cov ntaub ntawv ib ntus:
Yog hais tias ib tug txheej txheem sim nyeem los ntawm ib tug khoob pipeline ces
read(2)
yuav thaiv kom txog thaum cov ntaub ntawv muaj. Yog hais tias ib tug txheej txheem sim sau mus rau ib tug tag nrho pipeline, ceswrite(2)
yuav thaiv kom txog thaum muaj cov ntaub ntawv txaus tau nyeem los ntawm cov raj xa dej los ua cov ntawv sau.
Zoo li POSIX qhov yuav tsum tau muaj, qhov no yog ib qho khoom tseem ceeb: sau ntawv mus rau cov kav dej mus txog PIPE_BUF
bytes (tsawg kawg 512) yuav tsum yog atomic kom cov txheej txheem tuaj yeem sib txuas lus nrog ib leeg los ntawm cov kav dej hauv txoj kev uas cov ntaub ntawv tsis tu ncua (uas tsis muab cov kev lees paub zoo li no) ua tsis tau.
Thaum siv cov ntaub ntawv tsis tu ncua, tus txheej txheem tuaj yeem sau tag nrho nws cov txiaj ntsig rau nws thiab xa mus rau lwm tus txheej txheem. Los yog cov txheej txheem tuaj yeem ua haujlwm nyob rau hauv ib qho kev sib piv heev, siv cov kev taw qhia sab nraud (xws li semaphore) kom ceeb toom rau ib leeg thaum sau lossis nyeem tiav. Conveyors cawm peb ntawm tag nrho cov hassle no.
Peb tab tom nrhiav dab tsi?
Kuv yuav piav qhia hauv cov ntsiab lus yooj yim kom nws yooj yim dua rau koj los xav txog seb lub conveyor tuaj yeem ua haujlwm li cas. Koj yuav tsum tau faib cov tsis thiab qee lub xeev hauv kev nco. Koj yuav xav tau cov haujlwm ntxiv thiab tshem tawm cov ntaub ntawv los ntawm qhov tsis. Koj yuav xav tau qee qhov txhais tau tias hu ua haujlwm thaum nyeem thiab sau cov haujlwm ntawm cov ntaub ntawv piav qhia. Thiab koj yuav xav tau cov xauv kom ua raws li tus cwj pwm tshwj xeeb tau piav qhia saum toj no.
Tam sim no peb npaj txhij los nug cov lus nug hauv qab lub teeb ci ntsa iab kom paub meej lossis tsis lees paub peb tus qauv kev xav tsis meej. Tab sis nco ntsoov npaj rau qhov kev npaj txhij txog.
Peb saib qhov twg?
Kuv tsis paub qhov twg kuv luam ntawm phau ntawv nto moo yog "
Kev mus los ntawm TUHS cov ntaub ntawv yog zoo li mus xyuas lub tsev cia puav pheej. Peb tuaj yeem saib peb cov keeb kwm sib koom, thiab kuv muaj kev hwm rau ntau xyoo ntawm kev siv zog kom rov qab tau tag nrho cov ntaub ntawv no los ntawm me ntsis los ntawm cov kab xev qub thiab cov ntawv luam tawm. Thiab kuv paub zoo txog cov fragments uas tseem ploj lawm.
Tau txaus siab peb xav paub txog keeb kwm yav dhau los ntawm cov khoom siv conveyors, peb tuaj yeem saib cov kernels niaj hnub rau kev sib piv.
Los ntawm txoj kev, pipe
yog system hu xov tooj 42 nyob rau hauv lub rooj sysent[]
. Kev sib tsoo?
Tsoos Unix kernels (1970-1974)
Kuv nrhiav tsis tau ib yam dabtsi pipe(2)
tsis nyob hauv
TUHS hais tias
Unix 1973rd Edition yog qhov kawg version nrog cov ntsiav sau ua lus sib dhos, tab sis kuj yog thawj version nrog cov kav dej. Thaum xyoo XNUMX, kev ua haujlwm tau ua los txhim kho qhov thib peb tsab, cov ntsiav tau rov sau dua hauv C, thiab yog li thib plaub ntawm Unix tau tshwm sim.
Ib tus neeg nyeem tau pom ib qho scan ntawm ib daim ntawv uas Doug McIlroy tau npaj lub tswv yim ntawm "kev sib txuas cov kev pab cuam zoo li lub vaj hose."
Hauv Brian Kernighan phau ntawv
Thaum Unix tawm los, kuv qhov kev txaus siab nrog coroutines coj kuv mus nug OS tus kws sau ntawv, Ken Thompson, kom tso cai cov ntaub ntawv sau rau hauv cov txheej txheem mus tsis yog rau lub cuab yeej xwb, tab sis kuj tso tawm rau lwm cov txheej txheem. Ken txiav txim siab tias nws ua tau. Txawm li cas los xij, raws li tus minimalist, nws xav kom txhua qhov system ua haujlwm ua lub luag haujlwm tseem ceeb. Puas yog kev sau ncaj qha ntawm cov txheej txheem tiag tiag yog qhov txiaj ntsig zoo tshaj kev sau ntawv rau cov ntaub ntawv nruab nrab? Nws tsuas yog thaum kuv ua ib qho kev thov tshwj xeeb nrog lub npe ntxim nyiam "pipeline" thiab cov lus piav qhia ntawm syntax rau kev sib cuam tshuam ntawm cov txheej txheem uas Ken thaum kawg tau hais tias: "Kuv yuav ua!"
Thiab ua. Ib hmo muaj hmoo, Ken tau hloov pauv cov ntsiav thiab lub plhaub, kho ntau qhov kev pabcuam raws li tus qauv uas lawv lees txais cov tswv yim (uas tuaj yeem los ntawm lub raj xa dej), thiab kuj tau hloov npe cov ntaub ntawv. Hnub tom qab, cov kav dej tau pib siv dav hauv cov ntawv thov. Thaum kawg ntawm lub lim tiam, tus tuav ntaub ntawv tau siv lawv xa cov ntaub ntawv los ntawm cov txheej txheem lo lus mus rau lub tshuab luam ntawv. Ib me ntsis tom qab, Ken hloov tus thawj API thiab syntax rau wrapping siv cov kav dej nrog cov kev cai huv si, uas tau siv txij li thaum.
Hmoov tsis zoo, lub hauv paus code rau lub thib peb tsab Unix kernel tau ploj lawm. Thiab txawm hais tias peb muaj kernel qhov chaws sau hauv C
Peb muaj cov ntaub ntawv pov thawj rau pipe(2)
los ntawm ob qhov kev tshaj tawm, yog li koj tuaj yeem pib los ntawm kev tshawb nrhiav cov ntaub ntawv pipe(2)
yog sau ua lus sib dhos thiab xa rov qab tsuas yog ib daim ntawv piav qhia, tab sis twb muab cov kev xav tau yooj yim ua haujlwm:
System hu yeeb nkab tsim ib qho kev tawm tswv yim / tawm tswv yim hu ua lub raj xa dej. Cov ntaub ntawv rov qab piav qhia tuaj yeem siv los nyeem thiab sau ua haujlwm. Thaum ib yam dab tsi sau rau hauv cov raj xa dej, mus txog 504 bytes ntawm cov ntaub ntawv raug kaw, tom qab ntawd cov txheej txheem sau ntawv raug ncua. Thaum nyeem los ntawm cov raj xa dej, cov ntaub ntawv buffered raug muab tshem tawm.
Los ntawm xyoo tom ntej, cov ntsiav tau rov sau dua hauv C, thiab pipe(fildes)
Β»:
System hu yeeb nkab tsim ib qho kev tawm tswv yim / tawm tswv yim hu ua lub raj xa dej. Cov ntaub ntawv rov qab piav qhia tuaj yeem siv tau hauv kev nyeem thiab sau ntawv. Thaum ib yam dab tsi sau rau hauv lub raj xa dej, tus kov rov qab rau hauv r1 (resp. fildes[1]) yog siv, buffered rau 4096 bytes ntawm cov ntaub ntawv, tom qab uas cov txheej txheem sau raug tshem tawm. Thaum nyeem los ntawm cov raj xa dej, tus kov rov qab mus rau r0 (resp. fildes[0]) siv cov ntaub ntawv.
Nws yog xav tias thaum lub raj xa dej tau txhais, ob (lossis ntau dua) cov txheej txheem sib txuas lus (tsim los ntawm kev hu mus rau diav rawg) yuav hloov cov ntaub ntawv los ntawm cov raj xa dej siv hu nyeem ΠΈ sau ntawv.
Lub plhaub muaj ib tug syntax rau kev txhais ib tug linear array ntawm cov txheej txheem txuas los ntawm ib tug pipeline.
Kev hu xov tooj los nyeem los ntawm cov kav dej khoob (tsis muaj cov ntaub ntawv buffered) uas tsuas muaj ib qho kawg (txhua tus sau cov ntaub ntawv piav qhia raug kaw) rov qab "qhov kawg ntawm cov ntaub ntawv". Hu los sau rau hauv qhov xwm txheej zoo sib xws yog tsis quav ntsej.
Thaum ntxov
Thib 1975 ntawm Unix (XNUMX)
Cia peb pib nyeem Unix qhov chaws
Tau ntau xyoo phau ntawv Tsov ntxhuav yog tib daim ntawv ntawm Unix kernel muaj nyob sab nraum Bell Labs. Txawm hais tias daim ntawv tso cai thib rau tau tso cai rau cov kws qhia ntawv siv nws qhov chaws, daim ntawv tso cai thib xya tsis suav nrog qhov ua tau, yog li phau ntawv tau muab faib ua cov ntawv luam tawm tsis raug cai.
Niaj hnub no koj tuaj yeem yuav ib daim ntawv luam ntawm phau ntawv, daim npog uas qhia cov tub ntxhais kawm ntawm lub tshuab luam ntawv. Thiab ua tsaug rau Warren Toomey (leej twg pib TUHS qhov project) koj tuaj yeem rub tawm
Ntau tshaj 15 xyoo dhau los, kuv tau ntaus ib daim qauv ntawm qhov chaws muab rau hauv Tsov ntxhuav, vim kuv tsis nyiam qhov zoo ntawm kuv daim ntawv luam los ntawm cov tsis paub txog lwm cov ntawv luam. TUHS tseem tsis tau muaj thiab kuv tsis tau nkag mus rau qhov qub. Tab sis xyoo 1988, kuv pom ib daim kab xev qub 9-khiav uas muaj cov thaub qab ntawm PDP11 lub computer. Nws nyuaj rau qhia tias nws ua haujlwm, tab sis muaj qhov tsis zoo / usr / src / tsob ntoo uas feem ntau ntawm cov ntaub ntawv tau sau nrog xyoo 1979, uas txawm tias tom qab ntawd saib thaum ub. Nws yog xya tsab los yog nws cov derivative PWB, raws li kuv ntseeg.
Kuv coj qhov kev tshawb nrhiav los ua lub hauv paus thiab manually kho cov peev txheej rau lub thib rau tsab. Qee qhov chaws tseem zoo li qub, tab sis qee qhov yuav tsum tau kho me ntsis, hloov cov niaj hnub += token mus rau qhov qub =+. Qee yam raug tshem tawm yooj yim, thiab qee qhov yuav tsum tau sau dua tshiab, tab sis tsis ntau dhau.
Thiab hnub no peb tuaj yeem nyeem online ntawm TUHS qhov chaws ntawm lub thib rau tsab los ntawm
Los ntawm txoj kev, thaum xub thawj siab ib muag, lub ntsiab feature ntawm C-code ua ntej lub sij hawm ntawm Kernighan thiab Ritchie yog nws. brevity. Nws tsis yog ntau zaus uas kuv tuaj yeem ntxig cov lej tsis muaj kev kho kom haum rau qhov chaw nqaim ntawm kuv qhov chaw.
Thaum hauv paus
/*
* 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
Qhov loj tsis tau hloov txij li lub thib plaub tsab. Tab sis ntawm no peb pom, tsis muaj cov ntaub ntawv pej xeem, cov raj xa dej ib zaug siv cov ntaub ntawv ua cov ntaub ntawv khaws cia!
Raws li rau LARG cov ntaub ntawv, lawv sib raug rau
Nov yog qhov kev hu tiag tiag 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;
}
Cov lus piav qhia meej meej txog dab tsi tshwm sim ntawm no. Tab sis kev nkag siab cov cai tsis yooj yim li, ib feem yog vim txoj kev "R0
ΠΈ R1
system hu parameters thiab xa rov qab qhov tseem ceeb yog dhau.
Wb sim nrog
pipe()
yuav tsum dhau R0
ΠΈ R1
xa rov qab cov ntaub ntawv piav qhia tus lej nyeem thiab sau ntawv. falloc()
rov qab tus taw tes rau cov qauv ntaub ntawv, tab sis kuj "rov qab" ntawm u.u_ar0[R0]
thiab ib daim ntawv piav qhia. Ntawd yog, tus lej khaws cia hauv r
file descriptor rau kev nyeem ntawv thiab muab cov ntaub ntawv piav qhia rau kev sau ncaj qha los ntawm u.u_ar0[R0]
tom qab hu thib ob falloc()
.
Chij FPIPE
, uas peb tau teeb tsa thaum tsim cov raj xa dej, tswj tus cwj pwm ntawm kev ua haujlwm
/*
* 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);
}
/* β¦ */
}
Tom qab ntawd muaj nuj nqi readp()
Π² pipe.c
nyeem cov ntaub ntawv los ntawm cov kav dej. Tab sis nws yog qhov zoo dua los taug qab qhov kev siv pib los ntawm writep()
. Ib zaug ntxiv, cov cai tau dhau los ua qhov nyuaj vim yog cov lus pom zoo ntawm kev sib cav, tab sis qee cov ntsiab lus tuaj yeem raug tshem tawm.
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;
}
Peb xav sau bytes rau lub raj xa dej tawm u.u_count
. Ua ntej peb yuav tsum kaw lub inode (saib hauv qab no plock
/prele
).
Tom qab ntawd peb txheeb xyuas lub inode reference counter. Ntev npaum li ob qhov kawg ntawm lub raj xa dej tseem qhib, lub txee yuav tsum sib npaug li 2. Peb tuav ib qho txuas (los ntawm rp->f_inode
), yog li yog tias lub txee tsawg dua 2, nws yuav tsum txhais tau tias cov txheej txheem nyeem tau kaw nws qhov kawg ntawm cov kav dej. Hauv lwm lo lus, peb tab tom sim sau rau lub kav dej kaw, thiab qhov no yog qhov yuam kev. Thawj zaug yuam kev code EPIPE
thiab teeb liab SIGPIPE
tshwm sim nyob rau hauv lub thib rau tsab ntawm Unix.
Tab sis txawm tias lub conveyor qhib, nws yuav puv. Nyob rau hauv cov ntaub ntawv no, peb tso lub xauv thiab mus pw tsaug zog nyob rau hauv kev cia siab tias lwm cov txheej txheem yuav nyeem los ntawm lub raj xa dej thiab tso chaw txaus nyob rau hauv nws. Thaum sawv ntxov, peb rov qab mus rau qhov pib, kaw lub xauv dua thiab pib lub voj voog kaw tshiab.
Yog tias muaj qhov chaw dawb txaus hauv cov kav dej, ces peb sau cov ntaub ntawv rau nws siv i_size1
ntawm inode (yog tias lub raj xa dej khoob nws tuaj yeem sib npaug rau 0) qhia qhov kawg ntawm cov ntaub ntawv uas nws twb muaj. Yog tias muaj qhov chaw kaw txaus, peb tuaj yeem sau cov raj xa dej los ntawm i_size1
rau PIPESIZ
. Tom qab ntawd peb tso lub ntsuas phoo thiab sim tsa cov txheej txheem uas tos kom nyeem los ntawm cov raj xa dej. Peb rov qab mus rau qhov pib saib seb peb puas tuaj yeem sau ntau bytes raws li peb xav tau. Yog tias nws ua tsis tau, ces peb pib lub voj voog kaw tshiab.
Feem ntau cov parameter i_mode
inode yog siv los khaws kev tso cai r
, w
ΠΈ x
. Tab sis nyob rau hauv cov ntaub ntawv ntawm cov kav dej, peb qhia tias qee cov txheej txheem tseem tos rau kev sau lossis nyeem siv cov khoom siv IREAD
ΠΈ IWRITE
raws. Cov txheej txheem teev tus chij thiab hu sleep()
, thiab nws cia siab tias qee qhov txheej txheem yav tom ntej yuav ua rau wakeup()
.
Cov khawv koob tiag tiag tshwm sim hauv sleep()
ΠΈ wakeup()
. Lawv yog siv nyob rau hauv
/*
* 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) /* β¦ */
Cov txheej txheem uas ua rau sleep()
rau ib qho channel tshwj xeeb, tej zaum yuav tom qab waken los ntawm lwm cov txheej txheem, uas yuav ua rau wakeup()
rau tib lub channel. writep()
ΠΈ readp()
koom tes lawv cov yeeb yam los ntawm kev hu ua khub. nco ntsoov tias pipe.c
ib txwm muab qhov tseem ceeb PPIPE
thaum hu sleep()
, yog li ntawd sleep()
tej zaum yuav cuam tshuam los ntawm lub teeb liab.
Tam sim no peb muaj txhua yam kom nkag siab txog txoj haujlwm 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);
}
Koj tuaj yeem pom nws yooj yim dua los nyeem cov haujlwm no hauv qab mus rau sab saum toj. Cov ceg "nyeem thiab rov qab" feem ntau yog siv thaum muaj qee cov ntaub ntawv hauv cov kav dej. Hauv qhov no, peb siv f_offset
nyeem ntawv, thiab tom qab ntawd hloov kho tus nqi ntawm qhov sib thooj offset.
Tom qab nyeem ntawv, cov raj xa dej yuav khoob yog tias qhov kev nyeem offset tau mus txog i_size1
hauv inode. Peb rov pib dua txoj hauj lwm mus rau 0 thiab sim tsa ib qho txheej txheem uas xav sau rau hauv lub raj xa dej. Peb paub tias thaum lub conveyor puv, writep()
yuav pw tsaug zog ip+1
. Thiab tam sim no hais tias lub raj xa dej tsis muaj dab tsi, peb tuaj yeem tsim nws kom rov pib nws lub voj voog sau.
Yog tias koj tsis muaj dab tsi los nyeem, ces readp()
tuaj yeem teeb tsa chij IREAD
thiab pw tsaug zog ip+2
. Peb paub tias dab tsi yuav tsa nws sawv writep()
, thaum nws sau qee cov ntaub ntawv rau hauv cov kav dej.
Comments rau u
"Peb tuaj yeem kho lawv zoo li ib txwm ua haujlwm I / O uas siv cov ntaub ntawv, txoj haujlwm, tsis nyob hauv lub cim xeeb, thiab suav cov lej ntawm bytes nyeem lossis sau.
/*
* 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;
/* β¦ */
Raws li rau "conservative" thaiv, ces readp()
ΠΈ writep()
thaiv cov inode kom txog thaum lawv ua tiav lawv txoj haujlwm lossis tau txais cov txiaj ntsig (uas yog, hu wakeup
). plock()
ΠΈ prele()
ua haujlwm yooj yim: siv ntau txheej hu sleep
ΠΈ wakeup
tso cai rau peb sawv ntawm txhua tus txheej txheem uas xav tau lub xauv peb nyuam qhuav tso tawm:
/*
* 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);
}
}
Thaum xub thawj kuv tsis nkag siab tias yog vim li cas readp()
tsis ua prele(ip)
ua ntej hu wakeup(ip+1)
. Thawj qhov yog writep()
ua rau hauv nws lub voj voog, qhov no plock(ip)
, uas ua rau deadlock yog readp()
tseem tsis tau tshem kuv qhov thaiv, yog li cas cov cai yuav tsum ua haujlwm kom raug. Yog koj saib wakeup()
, tom qab ntawd nws tau pom tseeb tias nws tsuas yog cim cov txheej txheem pw tsaug zog raws li npaj ua tiav, yog li ntawd yav tom ntej sched()
tiag tiag launched nws. Yog li readp()
ua rau wakeup()
, tshem tawm lub xauv, teeb IREAD
thiab hu sleep(ip+2)
- tag nrho cov no ua ntej writep()
rov pib lub voj voog.
Qhov no ua tiav cov lus piav qhia ntawm cov khoom siv conveyors nyob rau hauv thib rau tsab. Cov cai yooj yim, qhov tshwm sim deb.
Xv6, ib qho yooj yim Unix zoo li ntsiav
Tsim cov kernel
Cov cai muaj qhov tseeb thiab xav txog kev siv 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()
teeb tsa lub xeev ntawm qhov seem ntawm qhov kev siv, uas suav nrog cov haujlwm piperead()
, pipewrite()
ΠΈ pipeclose()
. Qhov system hu tiag sys_pipe
yog wrapper siv nyob rau hauv
Linux 0.01
Linux 0.01 qhov chaws tuaj yeem pom. Nws yuav qhia kom kawm txog kev siv cov kav dej hauv nws fs
/pipe.c
. Qhov no siv ib qho inode los sawv cev rau lub raj xa dej, tab sis cov raj xa dej nws tus kheej tau sau rau hauv C niaj hnub no. Qhov no yog qhov ua haujlwm zoo li 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;
}
Tsis txawm saib cov qauv txhais, koj tuaj yeem paub seb qhov inode siv suav siv li cas los xyuas seb qhov kev sau ua haujlwm tau ua li cas. SIGPIPE
. Ntxiv rau kev ua haujlwm byte-by-byte, qhov haujlwm no yooj yim los piv nrog cov tswv yim tau piav qhia saum toj no. Txawm tias logic sleep_on
/wake_up
tsis zoo li neeg txawv teb chaws.
Niaj hnub nimno Linux kernels, FreeBSD, NetBSD, OpenBSD
Kuv khiav ceev nrooj los ntawm qee cov kernels niaj hnub. Tsis muaj leej twg muaj kev siv disk ntxiv lawm (tsis xav tsis thoob). Linux muaj nws tus kheej siv. Txawm hais tias peb niaj hnub BSD kernels muaj kev siv raws li cov cai uas tau sau los ntawm John Dyson, xyoo dhau los lawv tau dhau los ua qhov sib txawv ntawm ib leeg.
Nyeem fs
/pipe.c
(hauv Linux) los yog sys
/kern
/sys_pipe.c
(ntawm * BSD), nws yuav siv sij hawm kev mob siab tiag tiag. Hnub no txoj cai yog hais txog kev ua tau zoo thiab kev txhawb nqa rau cov yam ntxwv xws li vector thiab asynchronous I / O. Thiab cov ntsiab lus ntawm kev faib lub cim xeeb, ntsuas phoo thiab kev teeb tsa ntsiav txhua qhov sib txawv heev. Qhov no tsis yog dab tsi cov tsev kawm qib siab xav tau rau kev qhia txog kev ua haujlwm ua haujlwm.
Xijpeem, kuv xav mus khawb qee cov qauv qub (xws li tsim SIGPIPE
thiab rov qab los EPIPE
thaum sau ntawv rau lub raj xa dej kaw) hauv txhua qhov sib txawv niaj hnub no. Tej zaum kuv yuav tsis pom PDP-11 lub computer hauv lub neej tiag tiag, tab sis tseem muaj ntau yam uas yuav tsum tau kawm los ntawm cov lej uas tau sau ntau xyoo ua ntej kuv yug los.
Ib tsab xov xwm sau los ntawm Divi Kapoor hauv 2011:
Tau qhov twg los: www.hab.com