Yuav siv cov kav dej li cas hauv Unix

Yuav siv cov kav dej li cas hauv Unix
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 "Cov kav dej ua haujlwm li cas hauv Unix?"ua tawm tsis hais txog lub hauv paus qauv. Kuv tau xav paub thiab khawb rau hauv qhov qub los nrhiav cov lus teb.

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 cev (7) ΠΈ cev (2):

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, ces write(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 "Lions phau ntawv"nrog Unix 6 qhov chaws, tab sis ua tsaug rau Lub Unix Heritage Society koj tuaj yeem tshawb hauv online ntawm qhov chaws txawm tias qub versions ntawm Unix.

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 PDP-7 Unix (Lub Ib Hlis 1970), lossis hauv thawj tsab ntawm Unix (Lub Kaum Ib Hlis 1971), lossis hauv qhov tsis tiav qhov chaws thib ob tsab (Lub Rau Hli 1972).

TUHS hais tias thib peb tsab ntawm Unix (Lub Ob Hlis 1973) tau los ua thawj version nrog conveyors:

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."

Yuav siv cov kav dej li cas hauv Unix
Hauv Brian Kernighan phau ntawvUnix: Keeb Kwm thiab Memoir", nyob rau hauv keeb kwm ntawm qhov tshwm sim ntawm conveyors, cov ntaub ntawv no kuj tau hais tias: "... nws dai rau ntawm phab ntsa hauv kuv qhov chaw ua haujlwm ntawm Bell Labs rau 30 xyoo." Ntawm no kev xam phaj nrog McIlroy, thiab lwm zaj dab neeg los ntawm McIlroy txoj haujlwm, sau rau xyoo 2014:

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 thib plaub, tso tawm thaum lub Kaum Ib Hlis 1973, tab sis nws tau tawm ob peb lub hlis ua ntej tso tawm thiab tsis muaj cov kav dej siv. Nws yog ib qho kev txaj muag uas qhov chaws rau qhov kev ua haujlwm ntawm Unix lus dab neeg ploj, tej zaum mus ib txhis.

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 thib peb tsab (rau qee cov lus, hauv qab "manually", ib txoj hlua ntawm cov ntawv ^H, ua raws li tus lej hauv qab!). Qhov no proto-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 yeeb nkab (2) nyob rau hauv plaub tsab tau txais nws cov tsos niaj hnub nrog cov qauv "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 khaws cia kav dej siv siv rau mus rau lub thib tsib tsab ntawm Unix (Lub Rau Hli 1974), tab sis nws yuav luag zoo tib yam rau ib qho uas tau tshwm sim hauv qhov kev tso tawm tom ntej. Cov lus tsuas yog tau ntxiv, yog li koj tuaj yeem hla qhov thib tsib tsab.

Thib 1975 ntawm Unix (XNUMX)

Cia peb pib nyeem Unix qhov chaws thib rau tsab (Lub Tsib Hlis 1975). Ua tsaug ntau Tsov ntxhuav Nws yog qhov yooj yim dua los nrhiav dua li qhov chaw ntawm cov ntawv ua ntej:

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 PDF ntaub ntawv nrog qhov chaws rau lub thib rau tsab. Kuv xav muab koj lub tswv yim ntawm kev siv zog ntau npaum li cas mus rau hauv kev tsim cov ntaub ntawv:

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 archive, uas Dennis Ritchie muaj tes.

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 /usr/sys/ken/pipe.c muaj lus piav qhia (thiab yog, muaj ntau dua /usr/sys/dmr):

/*
 * 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 inode chij LARG, uas yog siv los ntawm "loj chaw nyob algorithm" rau txheej txheem indirect blocks txhawb nqa cov ntaub ntawv loj dua. Txij li thaum Ken hais tias nws zoo dua tsis txhob siv lawv, kuv yuav zoo siab coj nws lo lus rau nws.

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 "struct user uaΒ» thiab sau npe R0 ΠΈ R1 system hu parameters thiab xa rov qab qhov tseem ceeb yog dhau.

Wb sim nrog ialloc() muab tso rau hauv disk inode (index handle), thiab nrog kev pab falloc() - tso ob lub cim xeeb ntaub ntawv. Yog tias txhua yam ua tau zoo, peb yuav teeb tsa tus chij los txheeb xyuas cov ntaub ntawv no ua ob qhov kawg ntawm cov raj xa dej, taw tes rau tib lub inode (uas suav siv suav yuav raug teeb tsa rau 2), thiab kos lub inode raws li hloov kho thiab siv. Ua tib zoo mloog cov lus thov iput() hauv kev ua yuam kev los txo cov kev siv suav hauv cov inode tshiab.

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 rdwr() hauv sys2.chu rau I/O cov txheej txheem tshwj xeeb:

/*
 * 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 sau ntawv ( ). Parameter 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 slp.c, lub hauv paus ntawm lub npe nrov "Koj tsis xav kom nkag siab qhov no" lus. Hmoov zoo, peb tsis tas yuav nkag siab cov cai, tsuas yog saib qee cov lus pom:

/*
 * 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 nyeem ( ) peb nyeem cov ntaub ntawv ntau npaum li muaj pib los ntawm qhov tam sim no 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 readi( ) thiab writei( ) yuav pab koj nkag siab tias tsis txhob hla cov kev txwv ntawm "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.

7th tsab ntawm Unix (Lub Ib Hlis 1979) yog qhov kev tso tawm loj tshiab (plaub xyoo tom qab) uas tau qhia ntau yam tshiab thiab cov yam ntxwv ntawm cov ntsiav. Nws kuj tau txais kev hloov pauv tseem ceeb hauv kev sib txuas nrog kev siv hom casting, unions thiab ntaus pointers rau cov qauv. Txawm li cas los conveyor code xyaum tsis hloov. Peb tuaj yeem hla qhov tsab ntawv no.

Xv6, ib qho yooj yim Unix zoo li ntsiav

Tsim cov kernel xwv 6 cuam ​​tshuam los ntawm thib rau tsab ntawm Unix, tab sis nws tau sau nyob rau hauv niaj hnub C kom khiav ntawm x86 processors. Cov cai nyeem tau yooj yim thiab nkag siab. Ntxiv rau, tsis zoo li Unix cov peev txheej nrog TUHS, koj tuaj yeem sau nws, hloov kho, thiab khiav nws ntawm lwm yam uas tsis yog PDP 11/70. Yog li ntawd, cov kernel no tau siv dav hauv cov tsev kawm qib siab raws li cov ntaub ntawv kawm ntawm kev ua haujlwm. Qhov chaw nyob rau Github.

Cov cai muaj qhov tseeb thiab xav txog kev siv cev c, thim rov qab los ntawm qhov tsis nyob hauv lub cim xeeb tsis yog ib qho inode ntawm disk. Ntawm no kuv tsuas yog muab cov ntsiab lus ntawm "cov kav dej ua ke" thiab kev ua haujlwm 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 sysfile.c. Kuv xav kom nyeem nws tag nrho cov cai. Qhov nyuaj yog nyob rau theem ntawm lub hauv paus code ntawm lub thib rau tsab, tab sis nws yog ntau yooj yim dua thiab txaus siab rau kev nyeem ntawv.

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:Lub Linux Kernel Kev Siv Cov Yeeb thiab FIFOs" muab cov ntsiab lus ntawm yuav ua li cas cov kav dej (tseem) ua haujlwm hauv Linux. A tsis ntev los no cog lus hauv Linux piav qhia txog cov qauv ntawm kev sib txuas lus, uas nws muaj peev xwm tshaj cov ntaub ntawv ib ntus; thiab tseem qhia tau hais tias nyob deb npaum li cas cov kav dej tau los ntawm "kev ruaj ntseg kaw" ntawm lub thib rau tsab Unix kernel.

Tau qhov twg los: www.hab.com

Ntxiv ib saib