E faʻafefea ona faʻaogaina paipa i Unix

E faʻafefea ona faʻaogaina paipa i Unix
O lenei tusiga o loʻo faʻamatalaina ai le faʻatinoina o paipa i le fatu Unix. Sa ou le fiafia ona o se tala talu ai nei ua faaulutalaina "E faʻafefea ona galue paipa i Unix?» ua aliali mai e uiga i le fausaga i totonu. Na ou fiailoa ma su'e i puna tuai e su'e ai le tali.

O le a le mea o loo tatou talanoa ai?

Pipelines "atonu o le mea fou sili ona taua i Unix" - o se vaega faʻamalamalamaina o le filosofia autu a Unix o le tuʻufaʻatasia o polokalame laiti, ma le faʻaupuga masani:

$ echo hello | wc -c
6

O lenei fa'atinoga e fa'alagolago i le telefoni e tu'uina atu i le kernel pipe, lea o loʻo faʻamatalaina i luga o itulau faʻamaumauga paipa(7) и paipa(2):

O paipa e maua ai se ala e tasi le ala mo feso'otaiga vavave. O le paipa o loʻo i ai se faʻaoga (tusi le pito) ma se gaioiga (faitau pito). E mafai ona faitau fa'amatalaga tusitusia i totonu ole paipa ile fa'aulufalega.

Ole paipa e faia ile vala'au pipe(2), lea e toe faʻafoʻi ai faila faila e lua: o le tasi e faasino i le faʻaogaina o le paipa, o le lona lua i le gaosiga.

O le faʻasologa o gaioiga mai le faʻatonuga o loʻo i luga o loʻo faʻaalia ai le fausiaina o se paipa ma le tafe o faʻamaumauga mai le tasi gaioiga i le isi:

$ 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

O le faagasologa o matua e valaau pipe()e maua ai fa'amatalaga faila fa'apipi'i. E tusi le fa'asologa a le tamaititi i le isi fa'amatalaga ae o le isi fa'asologa e faitau fa'amatalaga tutusa mai le isi fa'amatalaga. O le atigi "igoa" faʻamatalaga 2 ma le 3 faʻatasi ma le dup4 e fetaui ma stdin ma stdout.

A aunoa ma paipa, e tatau i le atigi ona tusi le gaioiga o le tasi faagasologa i se faila ma paipa i se isi faiga e faitau ai faʻamatalaga mai le faila. O le i'uga, o le a tatou fa'ama'imau le tele o puna'oa ma avanoa tisiki. Ae ui i lea, o paipa e lelei mo le sili atu nai lo le na o le aloese mai faila le tumau:

Afai e taumafai se faiga e faitau mai se paipa gaogao, ona read(2) o le a poloka seia maua faʻamatalaga. Afai e taumafai se faiga e tusi i se paipa atoa, ona write(2) o le a poloka seia oʻo ina lava faʻamatalaga ua faitau mai le paipa e faʻamaeʻa ai le tusitusi.

E pei o le POSIX manaʻomia, o se mea taua lenei: tusitusi i le paipa e oʻo i PIPE_BUF bytes (a itiiti ifo i le 512) e tatau ona atomic ina ia mafai ona fesoʻotaʻi faʻagasologa o le tasi ma le isi e ala i le paipa i se auala e le mafai ai e faila masani (e le maua ai ia faʻamaoniga).

Faatasi ai ma se faila masani, e mafai e se faagasologa ona tusi uma ana galuega faatino i ai ma pasi atu i se isi faiga. Po'o fa'agasologa e mafai ona fa'agaoioi i se faiga fa'atutusa, fa'aaoga se masini fa'ailoga fafo (pei o se semaphore) e fa'ailoa ai e le tasi le isi e uiga i le mae'a o se tusi pe faitau. E lavea'ia i tatou e le 'au fa'asalalau mai nei fa'alavelave uma.

O le a le mea o loo tatou sailia?

O le a ou faʻamatalaina i luga o oʻu tamatamailima e faʻafaigofie ai ona e mafaufau pe faʻafefea ona galue se conveyor. E te manaʻomia le tuʻuina atu o se paʻu ma se setete e manatua. E te mana'omia ni galuega e fa'aopoopo ma aveese fa'amaumauga mai le pa. E te mana'omia se nofoaga e vala'au ai galuega a'o faitau ma tusitusi fa'agaioiga i faila fa'amatala. Ma e manaʻomia loka e faʻatino ai amioga faʻapitoa o loʻo faʻamatalaina i luga.

Ua matou sauni nei e su'esu'e le fa'apogai o le fatu i lalo o le moli malamalama e fa'amaonia pe fa'amaonia ai la matou fa'ata'ita'iga fa'aletonu o le mafaufau. Ae ia saunia i taimi uma mo mea e leʻi mafaufauina.

O fea o tatou vaavaai i ai?

Ou te le iloa po o fea o taoto ai la'u kopi o le tusi lauiloa.Tusi a leona« faʻatasi ai ma le Unix 6 source code, ae faʻafetai i Le Unix Heritage Society e mafai ona su'e i luga ole laiga puna code e oo lava i lomiga tuai o Unix.

O le feoai solo i totonu o le TUHS archives e pei o le asiasi i se falemataaga. E mafai ona tatou vaʻavaʻai i la tatou talaʻaga fefaʻasoaaʻi ma ou te faʻaaloalo mo le tele o tausaga o taumafaiga e toe faʻaleleia mea uma nei mea uma mai i kaseti tuai ma lolomi. Ma ou te matua nofouta i na vaega o loʻo misi pea.

I le faʻamalieina o lo tatou fia iloa e uiga i le talafaasolopito anamua o paipa, e mafai ona tatou vaʻavaʻai i 'au faʻaonaponei mo faʻatusatusaga.

I le ala, pipe o le numera telefoni 42 i le laulau sysent[]. Fa'afuase'i?

O fatu Unix masani (1970–1974)

Ou te lei mauaina se faailoga pipe(2) e le o totonu PDP-7 Unix (Ianuari 1970), pe i lomiga muamua Unix (Novema 1971), po'o le fa'ailoga fa'apogai le atoatoa lomiga lona lua (Iuni 1972).

Fai mai le TUHS lomiga lona tolu Unix (Fepuari 1973) o le lomiga muamua lea ma paipa:

O le lomiga lona tolu o Unix o le lomiga mulimuli lea ma se fatu na tusia i le assembler, ae o le uluai kopi foi ma paipa. I le 1973, o loʻo faʻagasolo galuega e faʻaleleia le lomiga lona tolu, na toe tusia le fatu i le C, ma o lea na fanau mai ai le lomiga lona fa o Unix.

Na maua e se tasi tagata faitau se faʻataʻitaʻiga o se pepa na tuʻuina atu ai e Doug McIlroy le manatu o le "faʻafesoʻotaʻi polokalame e pei o se faʻagogo togalaau."

E faʻafefea ona faʻaogaina paipa i Unix
I le tusi a Brian KernighanUnix: Ose Talafaasolopito ma se Faamanatuga", o le talafaasolopito o foliga vaaia o conveyors o loo taʻua ai foi lenei pepa: "... na tautau i luga o le puipui i loʻu ofisa i Bell Labs mo le 30 tausaga." O iinei faatalanoaga ma McIlroyma le isi tala mai O le galuega a McIlroy, na tusia i le 2014:

Ina ua aliali mai Unix, o loʻu naunau mo coroutines na mafua ai ona ou fesili i le tusitala o le OS, Ken Thompson, e faʻatagaina faʻamatalaga tusitusia i nisi o gaioiga e alu e le gata i le masini, ae faʻapea foʻi i le alu i se isi gaioiga. Na manatu Ken e mafai. Ae ui i lea, i le avea ai ma se laʻititi, na ia manaʻo i faʻalapotopotoga uma e faia se sao taua. O le tusitusi tuusa'o i le va o faiga o se mea sili ona lelei nai lo le tusitusi i se faila vavalalata? Ma naʻo le taimi na ou faia ai se talosaga faʻapitoa ma le igoa puʻeina "paipa" ma se faʻamatalaga o le syntax o fegalegaleaiga o gaioiga, na iu lava ina alaga Ken: "O le a ou faia!".

Ma sa faia. I se tasi afiafi mata'utia, na sui ai e Ken le fatu ma le atigi, fa'apipi'i le tele o polokalame masani e fa'ata'atia ai le auala latou te talia ai fa'aoga (atonu e sau mai se paipa), ma suia igoa o faila. O le aso na sosoo ai, o paipa sa matua faʻaaogaina i faʻaoga. E oo atu i le faaiuga o le vaiaso, na faaaoga e failautusi e auina atu ai pepa mai le faiga o upu i le lomitusi. I se taimi mulimuli ane, na suia ai e Ken le API muamua ma le syntax mo le afifiina o le faʻaogaina o paipa ma faʻasalalauga mama na faʻaaogaina talu mai lena taimi.

Ae paga lea, ua leiloa le source code mo le lomiga lona tolu o le kernel Unix. Ma e ui lava o loʻo ia i matou le kernel source code na tusia i le C lomiga lona fa, lea na faʻasalalau ia Novema 1973, ae na oʻo mai i ni nai masina aʻo lumanaʻi le faʻatagaina aloaia ma e le o aofia ai le faʻatinoina o paipa. O se fa'anoanoaga ua leiloa le fa'ailoga fa'apogai mo lenei fa'aaliga iloga Unix, masalo e fa'avavau.

E iai a matou tusitusiga fa'amaumauga mo pipe(2) mai faʻasalalauga uma e lua, o lea e mafai ai ona e amata ile suʻeina o faʻamaumauga lomiga lona tolu (mo nisi upu, vaseina "lima", o se manoa o ^H literals sosoo ai ma se vase!). O lenei proto-pipe(2) ua tusia i le assembler ma toe faafoi naʻo le tasi le faila faila, ae ua uma ona tuʻuina atu le faʻamoemoega autu:

System telefoni paipa faia se masini I/O e ta'ua o le paipa. E mafai ona fa'aoga le fa'amatalaga faila mo le faitau ma le tusitusi. Pe a tusia se mea i le paipa, e faʻapipiʻi i le 504 bytes o faʻamaumauga, a maeʻa ona faʻagata le faiga o tusitusiga. Pe a faitau mai le paipa, e ave faʻamaumauga faʻapipiʻi.

I le tausaga na sosoo ai, ua toe tusia le fatu i le C, ma paipa(2) lomiga lona fa maua lona foliga fa'aonaponei ma le fa'ata'ita'iga "pipe(fildes)"

System telefoni paipa faia se masini I/O e ta'ua o le paipa. E mafai ona fa'aogaina fa'amatalaga faila i le faitau ma le tusitusi. Pe a tusia se mea i le paipa, o le faʻamatalaga toe faʻafoʻi i le r1 (resp. fildes [1]) e faʻaaogaina, faʻapipiʻi i luga o le 4096 bytes o faʻamaumauga, a maeʻa ona faʻagata le faagasologa o le tusitusi. Pe a faitau mai le paipa, o le faʻamatalaga toe foʻi i le r0 (resp. fildes[0]) ave faʻamaumauga.

E fa'apea o le taimi lava e fa'amalamalamaina ai se paipa, e lua (pe sili atu) faiga fa'afeso'ota'i (faia e fa'atalosaga mulimuli ane. Tui) o le a pasi faʻamatalaga mai le paipa e faʻaaoga ai telefoni faitau и tusi.

O le atigi o loʻo i ai se syntax mo le faʻamalamalamaina o se laina laina o faiga e fesoʻotaʻi i se paipa.

Valaau e faitau mai se paipa gaogao (e leai ni fa'amaumauga fa'asalaina) e na'o le tasi le pito (tusi uma faila faila tapuni) toe fa'afo'i le "i'uga o faila". Tusi telefoni i se tulaga faapena e le amanaiaina.

Muamua fa'asaoina le fa'atinoga o paipa faasino i le lomiga lona lima o Unix (Iuni 1974), ae e toetoe lava a tutusa ma le lomiga na sosoo ai. Na'o fa'amatalaga fa'aopoopo, o lea e mafai ona fa'ase'e le lomiga lona lima.

Unix Sixth Lomiga (1975)

Amata ona faitau Unix source code lomiga lona ono (Me 1975). Faafetai tele i leona e sili atu le faigofie ona maua nai lo punaoa o lomiga muamua:

Mo le tele o tausaga o le tusi leona na o le pau lea o le pepa i luga o le fatu Unix o loʻo maua i fafo atu o Bell Labs. E ui o le laisene lona ono o le lomiga na mafai ai e faiaoga ona faʻaaoga lona puna code, ae o le laisene lona fitu na le aofia ai lenei avanoa, o lea na tufatufa atu ai le tusi i kopi tusitusi faasolitulafono.

I aso nei e mafai ona e faʻatau se kopi toe lolomi o le tusi, o le faʻavaa o loʻo faʻaalia ai tamaiti aoga i le kopi. Ma faafetai ia Warren Toomey (na amataina le poloketi TUHS), e mafai ona e sii maia Lomiga lona ono Puna PDF. Ou te fia tuʻuina atu ia te oe se manatu i le tele o taumafaiga na faia i le fatuina o le faila:

I luga atu o le 15 tausaga talu ai, sa ou taina i totonu se kopi o le faʻailoga puna na tuʻuina atu i totonu leonaaua ou te le fiafia i le lelei o la'u kopi mai se numera le iloa o isi kopi. E le'i iai lava TUHS, ma ou te le'i maua le avanoa i puna tuai. Ae i le 1988 na ou maua ai se lipine tuai ma 9 ala sa i ai se sao mai se komepiuta PDP11. Sa faigata ona iloa pe aoga, ae o loʻo i ai se / usr / src / laau o loʻo faʻailogaina ai le tele o faila i le 1979, lea na foliga mai anamua. O le lomiga lona fitu, poʻo se faʻasologa o le PWB, na ou mafaufau ai.

Na ou ave le sailiga e fai ma faavae ma faasaʻo lima ia punaoa i le setete o le lomiga lona ono. O se vaega o le code na tumau pea, o se vaega e tatau ona teuteu teisi, suia le faʻailoga faʻaonaponei += i le =+ ua tuai. Sa na'o le tapeina o se mea, ma sa tatau ona toe tusia atoa se mea, ae le tele naua.

Ma o aso nei e mafai ona tatou faitau i luga ole laiga i TUHS le code source o le lomiga lona ono o archive, lea sa i ai le lima o Dennis Ritchie.

I le auala, i le tepa muamua, o le vaega autu o le C-code ao leʻi oʻo i le vaitaimi o Kernighan ma Ritchie o lona uiga. pupuu. E le masani ona mafai ona ou fa'aofiina snippets o code e aunoa ma se fa'ata'ita'iga tele ina ia fetaui ma se fa'aaliga vaapiapi i luga o la'u saite.

I le amataga /usr/sys/ken/pipe.c o loʻo i ai se faʻamatalaga faʻamatalaga (ma ioe, e tele atu /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

E le'i suia lava le lapo'a o le pa'u talu mai le lomiga lona fa. Ae o iinei tatou te vaʻai ai, e aunoa ma ni faʻamatalaga lautele, o paipa na faʻaaogaina faila e pei o le teuina i tua!

Ae mo faila LARG, e fetaui ma inode-fu'a LARG, lea e faʻaaogaina e le "large addressing algorithm" e faʻatautaia poloka le tuusao e lagolago ai faiga faila tetele. Talu ai na fai mai Ken e sili atu le aua le faaaogaina, o lea ou te fiafia ai e talia lana upu.

O le faiga moni lea 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;
}

O loʻo faʻamatala manino mai e le faʻamatalaga le mea o loʻo tupu iinei. Ae e le faigofie tele ona malamalama i le tulafono, o se vaega ona o le auala "struct user u»ma resitala R0 и R1 fa'asologa o vala'au ma toe fa'afo'i ua pasia.

Tatou taumafai ma ialloc() tuu i luga o le tisiki inode (inode), ma le fesoasoani falloc() - faleoloa lua faila. Afai e lelei mea uma, o le a matou seti fuʻa e iloa ai faila nei o pito e lua o le paipa, faʻasino i latou i le inode lava e tasi (o lona faʻamatalaga e avea ma 2), ma faailoga le inode ua suia ma faʻaoga. Fa'alogo i talosaga i iput() i auala sese e faʻaititia ai le numera o faʻamatalaga i le inode fou.

pipe() e tatau ona ala R0 и R1 toe faafoi numera faila faila mo le faitau ma le tusitusi. falloc() toe fa'afo'i mai se fa'ailoga i se fausaga faila, ae "toe fo'i" e ala i u.u_ar0[R0] ma se fa'amatalaga faila. O lona uiga, o le code o loʻo teuina i totonu r faila fa'amatalaga mo le faitau ma tofia se fa'amatalaga mo le tusitusi sa'o mai u.u_ar0[R0] ina ua uma le valaau faalua falloc().

Flag FPIPE, lea matou te setiina pe a fatuina le paipa, pulea le amio o le galuega rdwr() i le sys2.c, lea e taʻua ai masani I / O masani:

/*
 * 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);
    }
        /* … */
}

Ona sosoo ai lea ma le galuega readp() в pipe.c faitau fa'amaumauga mai le paipa. Ae sili atu le suʻeina o le faʻatinoga amata mai writep(). Toe fo'i, ua sili atu le lavelave o le tulafono ona o le natura o le felafolafoaiga o le pasia o le tauaofiaga, ae o nisi auiliiliga e mafai ona aveese.

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;
}

Matou te mananaʻo e tusi bytes i totonu o le paipa u.u_count. Muamua e tatau ona tatou lokaina le inode (silasila i lalo plock/prele).

Ona matou siaki lea o le numera o le inode. Afai lava e matala pito uma e lua o le paipa, e tatau ona 2 le fata. Matou te pipiimau i le tasi sooga (mai rp->f_inode), o lea afai o le fata e itiiti ifo i le 2, o lona uiga o le faagasologa o le faitau ua tapunia lona pito o le paipa. I se isi faaupuga, o loʻo matou taumafai e tusi i se paipa tapuni, o se mea sese. Muamua code sese EPIPE ma faailo SIGPIPE na fa'aalia i le lomiga lona ono o Unix.

Ae tusa lava pe tatala le conveyor, atonu e tumu. I lenei tulaga, matou te tatalaina le loka ma alu e momoe i le faʻamoemoe o le a faitau se isi gaioiga mai le paipa ma faʻasaʻoloto le avanoa i totonu. A tatou ala i luga, tatou te toe foi i le amataga, toe tautau le loka ma amata se taamilosaga tusitusi fou.

Afai e lava le avanoa avanoa i le paipa, ona matou tusia lea o faʻamatalaga i ai e faʻaaoga ai tusi (). Parameter i_size1 ole inode'a (fa'atasi ai ma se paipa gaogao e mafai ona tutusa ma le 0) fa'asino ile pito o fa'amaumauga ua uma ona iai. Afai e lava le avanoa e tusi ai, e mafai ona matou faʻatumu le paipa mai i_size1 i PIPESIZ. Ona matou tatalaina lea o le loka ma taumafai e fafagu i luga soʻo se faagasologa o loʻo faʻatali e faitau mai le paipa. Matou te toe foʻi i le amataga e vaʻai pe na mafai ona matou tusia le tele o bytes pe a manaʻomia. Afai e le manuia, ona tatou amataina lea o se taamilosaga fou o le pueina.

E masani lava fa'amaufa'ailoga i_mode ua fa'aogaina le inode e teu ai fa'atagaga r, w и x. Ae i le tulaga o paipa, matou te faʻaalia o loʻo faʻatali se gaioiga mo se tusi pe faitau e faʻaaoga ai fasi IREAD и IWRITE taitasi. O le faagasologa e seti ai le fuʻa ma valaau sleep(), ma ua faamoemoe o le a valaau mai se isi faiga i le lumanai wakeup().

O le togafiti faataulaitu moni e tupu i totonu sleep() и wakeup(). O loʻo faʻatinoina i totonu slp.c, o le puna o le lauiloa "E le o faamoemoe e te malamalama i lenei" faamatalaga. O le mea e laki ai, e le tatau ona tatou malamalama i le tulafono, naʻo le vaʻai i ni faʻamatalaga:

/*
 * Give up the processor till a wakeup occurs
 * on chan, at which time the process
 * enters the scheduling queue at priority pri.
 * The most important effect of pri is that when
 * pri<0 a signal cannot disturb the sleep;
 * if pri>=0 signals will be processed.
 * Callers of this routine must be prepared for
 * premature return, and check that the reason for
 * sleeping has gone away.
 */
sleep(chan, pri) /* … */

/*
 * Wake up all processes sleeping on chan.
 */
wakeup(chan) /* … */

O le faagasologa e valaau sleep() mo se auala faapitoa, e mafai ona toe fafagu e se isi faiga, lea o le a valaau wakeup() mo le ala lava lea e tasi. writep() и readp() fa'amaopoopo a latou gaioiga e ala i ia vala'au fa'atasi. matau lena pipe.c faamuamua i taimi uma PPIPE pe a valaauina sleep(), faapena uma lava sleep() e mafai ona faalavelaveina e se faailo.

O lea ua tatou maua mea uma e malamalama ai i le galuega 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);
}

Atonu e faigofie ona e faitau i lenei galuega mai lalo i luga. Ole lala "faitau ma toe foʻi" e masani ona faʻaaogaina pe a iai ni faʻamatalaga ile paipa. I lenei tulaga, matou te faʻaaogaina faitau() faitau le tele o faʻamatalaga e maua mai i le taimi nei f_offset faitau, ona faafou lea o le tau o le offset talafeagai.

I faitauga mulimuli ane, o le a gaogao le paipa pe a o'o i le fa'asologa o le faitau i_size1 i le inode. Matou te toe setiina le tulaga i le 0 ma taumafai e fafagu i luga soʻo se gaioiga e manaʻo e tusi i le paipa. Matou te iloa pe a tumu le conveyor, writep() moe i luga ip+1. Ma o lea ua gaogao le paipa, e mafai ona tatou fafagu i luga e toe amata lana taamilosaga tusitusi.

Afai e leai se mea e faitau ai, ona readp() mafai ona seti se fu'a IREAD ma moe i luga ip+2. Ua tatou iloa le mea o le a fafagu ai o ia writep()pe a tusia ni faʻamatalaga i le paipa.

Fa'amatalaga ile faitau() ma tusi() o le a fesoasoani ia te oe ia malamalama i lena mea nai lo le pasi atu i vaega "u»e mafai ona tatou faia e pei o galuega masani I/O e ave se faila, se tulaga, se pa puipui i le manatua, ma faitau le numera o paita e faitau pe tusitusi.

/*
 * 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;
/* … */

Ae mo le "conservative" poloka, o lona uiga readp() и writep() loka inodes se'ia mae'a pe maua se fa'ai'uga (e pei o le vala'au wakeup). plock() и prele() galue faigofie: faʻaaogaina se seti o telefoni sleep и wakeup fa'ataga matou e fafagu i luga so'o se faiga e mana'omia ai le loka na matou fa'ato'a tatalaina:

/*
 * Lock a pipe.
 * If its already locked, set the WANT bit and sleep.
 */
plock(ip)
int *ip;
{
    register *rp;

    rp = ip;
    while(rp->i_flag&ILOCK) {
        rp->i_flag =| IWANT;
        sleep(rp, PPIPE);
    }
    rp->i_flag =| ILOCK;
}

/*
 * Unlock a pipe.
 * If WANT bit is on, wakeup.
 * This routine is also used to unlock inodes in general.
 */
prele(ip)
int *ip;
{
    register *rp;

    rp = ip;
    rp->i_flag =& ~ILOCK;
    if(rp->i_flag&IWANT) {
        rp->i_flag =& ~IWANT;
        wakeup(rp);
    }
}

I le taimi muamua sa ou le malamalama pe aisea readp() e le mafua ai prele(ip) a o lei valaau wakeup(ip+1). O le mea muamua writep() valaau i lona matasele, lenei plock(ip), lea e iu ai i se faaletonu pe afai readp() e le'i aveesea lana poloka, o lea e tatau ona sa'o lelei le code. Afai e te tilotilo i ai wakeup(), e manino lava e naʻo le faʻailogaina o le moe o loʻo sauni mo le faʻataunuʻuina, ina ia i le lumanaʻi. sched() na matua tatalaina lava. O lea readp() mafuaʻaga wakeup(), tatala, seti IREAD ma valaau sleep(ip+2)- nei mea uma muamua writep() toe amata le taamilosaga.

Ua mae'a le fa'amatalaga o paipa i le lomiga lona ono. Fa'ailoga faigofie, fa'auiga mamao.

Lomiga Fitu Unix (Ianuari 1979) o se faʻasalalauga tele fou (fa tausaga mulimuli ane) na faʻaalia ai le tele o faʻaoga fou ma foliga o fatu. Ua o'o fo'i i suiga tetele e feso'ota'i ma le fa'aogaina o le tu'i ituaiga, fa'atasi ma fa'ailoga fa'aoga i fausaga. Peitai code laina paipa toetoe lava a le suia. E mafai ona tatou misia lenei lomiga.

Xv6, o se fatu faigofie e pei o le Unix

E fatu ai se nucleus Xv6 fa'aaafia i le lomiga lona ono o Unix, ae na tusia i le C fa'aonaponei e tamo'e i le x86 processors. O le code e faigofie ona faitau ma malamalama. E le gata i lea, e le pei o punaoa Unix ma TUHS, e mafai ona e tuʻufaʻatasia, suia, ma faʻatautaia i luga o se mea e ese mai i le PDP 11/70. O le mea lea, o lenei autu o loʻo faʻaaogaina lautele i iunivesite e fai ma aʻoaʻoga i luga o faiga faʻaoga. Punavai o loʻo i luga ole Github.

O le code o loʻo i ai se faʻatinoga manino ma mafaufau lelei paipa.c, lagolagoina e se pa puipui i le manatua nai lo se inode i luga ole disk. O lea ou te tuʻuina atu naʻo le faʻamatalaga o le "faʻasologa o paipa" ma le galuega 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() fa'atulagaina le tulaga o isi vaega uma o le fa'atinoga, lea e aofia ai galuega piperead(), pipewrite() и pipeclose(). O le telefoni faiga moni sys_pipe o se afifi ua fa'atinoina i totonu sysfile.c. Ou te fautuaina e faitau uma ana code. O le lavelave o loʻo i le tulaga o le faʻailoga puna o le lomiga lona ono, ae e sili atu ona faigofie ma sili atu ona manaia le faitau.

Linux 0.01

E mafai ona e mauaina le code source mo Linux 0.01. O le a aoga le suʻesuʻeina o le faʻatinoina o paipa i lana fs/pipe.c. O iinei, o le inode o loʻo faʻaaogaina e fai ma sui o le paipa, ae o le pipeline lava ia o loʻo tusia i le C faʻaonaponei. O le foliga lea o le galuega 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;
}

E tusa lava pe aunoa ma le tilotilo i faʻamatalaga faʻavae, e mafai ona e iloa pe faʻafefea ona faʻaogaina le numera o le inode e siaki ai pe o se gaioiga tusitusi e maua ai. SIGPIPE. I le faaopoopo atu i le byte-by-byte galuega, o lenei galuega e faigofie ona faʻatusatusa i manatu o loʻo i luga. E oo lava i manatu sleep_on/wake_up e le foliga ese.

Linux Kernels fa'aonaponei, FreeBSD, NetBSD, OpenBSD

Sa vave ona ou alu i luga o ni fatu faaonaponei. E leai se tasi oi latou ua i ai se faʻatinoga faʻavae tisiki (e le o se mea e ofo ai). O Linux e iai lana lava faʻatinoga. Ma e ui lava o fatu BSD faʻaonaponei e tolu o loʻo i ai faʻatinoga e faʻavae i luga o le code na tusia e John Dyson, i le aluga o tausaga ua matua ese mai le tasi i le isi.

E faitau fs/pipe.c (i luga o Linux) poʻo sys/kern/sys_pipe.c (i luga o *BSD), e manaʻomia le faʻamaoni moni. Fa'atinoga ma le lagolago mo foliga e pei o le vector ma le asynchronous I/O e taua ile code i aso nei. Ma o faʻamatalaga o le faʻasoaina o manatua, loka, ma le faʻatulagaina o fatu e matua ese uma lava. E le'o le mea lea e mana'omia e iunivesite mo se kosi folasaga i faiga fa'aoga.

I soo se tulaga, sa manaia mo aʻu le suʻeina o ni nai mamanu tuai (mo se faʻataʻitaʻiga, faʻatupu SIGPIPE ma toe foi mai EPIPE pe a tusi i se paipa tapuni) i nei mea uma, e matua ese lava, fatu faʻaonapo nei. Masalo o le a ou le vaʻai i se komepiuta PDP-11 ola, ae o loʻo i ai pea le tele o mea e aʻoaʻoina mai le code na tusia i ni nai tausaga ae ou te leʻi fanau mai.

Na tusia e Divi Kapoor i le 2011, le tusiga "Le Linux Kernel Fa'atinoina o Paipa ma FIFOo se aotelega o le auala e galue ai paipa Linux (e oʻo mai i le taimi nei). A ta'utinoga talu ai nei i le linux fa'aalia le fa'ata'ita'iga o feso'ota'iga paipa, o latou gafatia e sili atu nai lo faila le tumau; ma faʻaalia ai foʻi le mamao o paipa ua alu ese mai le "loka malu puipuia" i le lona ono lomiga Unix kernel.

puna: www.habr.com

Faaopoopo i ai se faamatalaga