Liphaephe li kengoa tšebetsong joang ho Unix

Liphaephe li kengoa tšebetsong joang ho Unix
Sengoliloeng sena se hlalosa ts'ebetsong ea liphaephe ho Unix kernel. Ke ne ke batla ke nyahame hore sengoloa sa morao tjena se nang le sehlooho se reng "Liphaephe li sebetsa joang Unix?"ea etsahala ha mabapi le sebopeho sa ka hare. Ke ile ka labalabela ho tseba eaba ke sheba mehloli ea khale ho fumana karabo.

Re bua ka eng?

Liphaephe, "mohlomong tse qapiloeng ka ho fetisisa ho Unix," ke tšobotsi e hlalosang filosofi ea Unix ea ho hokahanya mananeo a manyenyane hammoho, hammoho le letšoao le tloaelehileng molaong oa taelo:

$ echo hello | wc -c
6

Ts'ebetso ena e ipapisitse le mohala oa sistimi e fanoeng ke kernel pipe, e hlalositsoeng maqepheng a litokomane peipi(7) и peipi(2):

Liphaephe li fana ka mocha o le mong oa puisano ea lipuisano. Pipeline e na le ho kenya (ho ngola qetellong) le tlhahiso (bala qetellong). Lintlha tse ngotsoeng ho kenngoa ha pipeline li ka baloa ho tsoa.

Pipeline e entsoe ka mohala pipe(2), e khutlisetsang litlhaloso tse peli tsa faele: e 'ngoe e bua ka ho kenngoa ha pipeline, ea bobeli e bua ka tlhahiso.

Tlhahiso e tsoang ho taelo e ka holimo e bonts'a ho thehoa ha pipeline le phallo ea data ho eona ho tloha ts'ebetsong e 'ngoe ho ea ho e' ngoe:

$ 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

Ts'ebetso ea motsoali e bitsa pipe()ho fumana litlhaloso tsa lifaele tse kentsoeng. Ts'ebetso e le 'ngoe ea ngoana e ngolla letsoho le le leng,' me ts'ebetso e 'ngoe e bala data e tšoanang ho tsoa ho sebapa se seng. Khetla e sebelisa dup2 ho "rename" litlhaloso tsa 3 le 4 ho tsamaisana le stdin le stdout.

Ntle le liphaephe, khetla e tla tlameha ho ngola sephetho sa ts'ebetso e le 'ngoe faeleng ebe e e fetisetsa ts'ebetsong e' ngoe ho bala data ho tsoa faeleng. Ka lebaka leo, re ne re tla senya lisebelisoa tse ngata le sebaka sa disk. Leha ho le joalo, liphaephe li ntle eseng feela hobane li u lumella ho qoba ts'ebeliso ea lifaele tsa nakoana:

Haeba ts'ebetso e leka ho bala ho tsoa phaepheng e se nang letho, joale read(2) e tla thibela ho fihlela data e fumaneha. Haeba ts'ebetso e leka ho ngolla pipeline e feletseng, joale write(2) e tla thibela ho fihlela data e lekaneng e baloa ho tloha phaepheng ea ho ngola.

Joalo ka tlhokahalo ea POSIX, ena ke thepa ea bohlokoa: ho ngolla lipeipi ho fihlela PIPE_BUF li-byte (bonyane 512) li tlameha ho ba liathomo e le hore lits'ebetso li ka buisana ka liphaephe ka tsela eo lifaele tse tloaelehileng (tse sa faneng ka litiisetso tse joalo) li ke keng tsa khona.

Ha u sebelisa faele e tloaelehileng, ts'ebetso e ka ngola tlhahiso eohle ea eona ho eona ebe e fetisetsa ts'ebetsong e 'ngoe. Kapa lits'ebetso li ka sebetsa ka mokhoa o ts'oanang haholo, ho sebelisoa mokhoa oa ho bonts'a kantle (joalo ka semaphore) ho tsebisana ha ho ngola kapa ho bala ho felile. Li-conveyors li re pholosa mathateng ana kaofela.

Re batla eng?

Ke tla e hlalosa ka mantsoe a bonolo e le hore ho be bonolo ho uena ho nahana hore na conveyor e ka sebetsa joang. U tla hloka ho fana ka buffer le boemo bo itseng mohopolong. U tla hloka lits'ebetso ho kenya le ho tlosa data ho buffer. U tla hloka mekhoa e meng ea ho letsetsa lits'ebetso nakong ea ho bala le ho ngola ts'ebetso ho litlhaloso tsa faele. 'Me u tla hloka liloko ho kenya ts'ebetsong boitšoaro bo khethehileng bo hlalositsoeng ka holimo.

Hona joale re se re itokiselitse ho hlahloba khoutu ea mohloli oa kernel tlas'a lebone le khanyang ho netefatsa kapa ho hanyetsa mohlala oa rona o sa hlakang oa kelello. Empa kamehla u itokisetse lintho tse sa lebelloang.

Re shebile kae?

Ha ke tsebe hore na kopi ea ka ea buka e tsebahalang e hokae "Buka ea litau"ka khoutu ea mohloli oa Unix 6, empa ka lebaka la Mokhatlo oa Unix Heritage u ka batla Inthaneteng ho mohloli oa khoutu esita le liphetolelo tsa khale tsa Unix.

Ho lelera ka har'a polokelo ea khale ea TUHS ho tšoana le ho etela musiamo. Re ka sheba nalane ea rona e arolelanoang, 'me ke na le tlhompho bakeng sa lilemo tse ngata tsa boiteko ba ho khutlisa thepa ena kaofela butle-butle ho tsoa litheiping tsa khale le likhatisong. 'Me ke tseba hantle ka likhechana tseo tse ntseng li le sieo.

Ha re se re khotsofetse tabatabelo ea rōna ea histori ea boholo-holo ea lipalangoang, re ka bapisa lithollo tsa mehleng ea kajeno.

Tseleng, pipe ke nomoro ea mohala oa sistimi 42 tafoleng sysent[]. Ka tsietsi?

Lithollo tsa setso tsa Unix (1970-1974)

Ha kea fumana mehlala pipe(2) leha e le ho PDP-7 Unix (Pherekhong 1970), leha e le ka khatiso ea pele ea Unix (November 1971), leha e le ka khoutu e sa fellang ea mohloli khatiso ea bobeli (June 1972).

TUHS e bolela joalo khatiso ea boraro ea Unix (Hlakola 1973) e bile mofuta oa pele o nang le li-conveyors:

Unix 1973rd Edition e bile mofuta oa ho qetela o nang le kernel e ngotsoeng ka puo ea kopano, empa hape le mofuta oa pele o nang le liphaephe. Ka XNUMX, ho ile ha etsoa mosebetsi oa ho ntlafatsa khatiso ea boraro, kernel e ile ea ngoloa bocha ka C, eaba ho hlaha khatiso ea bone ea Unix.

'Mali e mong o ile a fumana setšoantšo sa tokomane eo ho eona Doug McIlroy a ileng a fana ka maikutlo a "ho hokahanya mananeo a kang hose ea jareteng."

Liphaephe li kengoa tšebetsong joang ho Unix
Bukeng ea Brian KernighanUnix: Histori le Memoir", nalaneng ea ho hlaha ha li-conveyors, tokomane ena e boetse e boleloa: "... e fanyehiloe leboteng ofising ea ka Bell Labs ka lilemo tse 30." Mona puisano le McIlroy, le pale e 'ngoe e tsoang ho Mosebetsi oa McIlroy, o ngotsoeng ka 2014:

Ha Unix e tsoa, ​​ho khahloa ha ka ke li-coroutine ho ile ha etsa hore ke botse mongoli oa OS, Ken Thompson, ho lumella data e ngotsoeng ts'ebetsong hore e se ke ea e-ba sesebelisoa feela, empa hape le ho hlahisa mokhoa o mong. Ken o ile a etsa qeto ea hore hoa khoneha. Leha ho le joalo, joalo ka minimalist, o ne a batla hore ts'ebetso e 'ngoe le e' ngoe ea sistimi e phethe karolo ea bohlokoa. Na ho ngola ka kotloloho lipakeng tsa lits'ebetso ke monyetla o moholo ho feta ho ngolla faele e bohareng? E bile feela ha ke etsa tlhahiso e itseng ka lebitso le khahlang "pipeline" le tlhaloso ea syntax bakeng sa tšebelisano lipakeng tsa lits'ebetso moo Ken a ileng a qetella a hooa: "Ke tla e etsa!"

Mme e entse. Mantsiboeeng a mang a mahlonoko, Ken o ile a fetola kernel le khetla, a lokisa mananeo a 'maloa a tloaelehileng ho tiisa hore na ba amohela ho kenya letsoho joang (e ka hlahang ka pipeline), hape a fetola mabitso a lifaele. Letsatsing le hlahlamang, liphaephe li ile tsa qala ho sebelisoa haholo likopong. Qetellong ea beke, bangoli ba ne ba li sebelisa ho romela litokomane ho tloha ho li-word processor ho ea ho mochine oa khatiso. Nakoana hamorao, Ken o ile a nkela sebaka sa API le syntax ea pele bakeng sa ho phuthela tšebeliso ea lipeipi ka likopano tse hloekileng, tse 'nileng tsa sebelisoa ho tloha ka nako eo.

Ka bomalimabe, khoutu ea mohloli bakeng sa khatiso ea Unix kernel e lahlehile. Mme leha re na le khoutu ea mohloli oa kernel e ngotsoeng ho C khatiso ea bone, e lokollotsoeng ka November 1973, empa e ile ea tsoa likhoeli tse 'maloa pele ho lokolloa ka molao' me ha e na ts'ebetsong ea lipeipi. Ke masoabi hore ebe khoutu ea mohloli bakeng sa ts'ebetso ena e tsebahalang ea Unix e lahlehile, mohlomong ka ho sa feleng.

Re na le litokomane tsa mongolo bakeng sa pipe(2) ho tsoa litokollong ka bobeli, kahoo o ka qala ka ho batla litokomane khatiso ea boraro (bakeng sa mantsoe a itseng, a thalletsoe “ka letsoho”, letoto la mantsoe a hlalosang mantsoe ^H, le lateloa ke mongolo oa underscore!). Setšoantšo sena -pipe(2) e ngotsoe ka puo ea kopano 'me e khutlisa tlhaloso e le' ngoe feela ea faele, empa e se e fana ka ts'ebetso ea mantlha e lebelletsoeng:

Mohala oa sistimi phala e theha mokhoa oa ho kenya letsoho/ho tsoa o bitsoang pipeline. Tlhaloso ea faele e khutlisitsoeng e ka sebelisoa bakeng sa ts'ebetso ea ho bala le ho ngola. Ha ntho e 'ngoe e ngotsoe ho pipeline, ho fihlela ho li-byte tse 504 tsa data li bolokiloe, ka mor'a moo mokhoa oa ho ngola o emisoa. Ha u bala lipeipi, data e bolokiloeng e tlosoa.

Selemong se latelang kernel e ne e se e ngotsoe bocha ka C, le pipe(2) khatisong ea bone e fumane ponahalo ea eona ea sejoale-joale ka mohlala "pipe(fildes)"

Mohala oa sistimi phala e theha mokhoa oa ho kenya letsoho/ho tsoa o bitsoang pipeline. Litlhaloso tsa faele tse khutlisitsoeng li ka sebelisoa ts'ebetsong ea ho bala le ho ngola. Ha ho ngoloa ntho e 'ngoe ho phaephe, ho sebelisoa molamu o khutlisitsoeng ka r1 (resp. fildes[1]), o bolokiloe ho li-byte tse 4096 tsa data, ka mor'a moo mokhoa oa ho ngola o emisoa. Ha u bala ho tloha phaepheng, molamu o khutlela ho r0 (resp. fildes[0]) o nka data.

Ho nahanoa hore hang ha phaephe e hlalosoa, mekhoa e 'meli (kapa ho feta) ea puisano (e entsoeng ka mehala e latelang ho Fereko) e tla fetisetsa data ho tsoa ho pipeline ho sebelisa mehala bala и ngola.

Khetla e na le syntax bakeng sa ho hlalosa letoto la lits'ebetso tse hoketsoeng ke liphaephe.

Mehala e lokelang ho baloa ho tsoa ho phaephe e se nang letho (e se nang data e bolokiloeng) e nang le pheletso e le 'ngoe feela (litlhaloso tsohle tsa faele ea ho ngola li koetsoe) li khutlisa "qetellong ea faele". Mehala ea ho ngola boemong bo tšoanang e hlokomolohuoa.

Esale pele ts'ebetsong ea lipeipi tse bolokiloeng e bolela ho ea khatisong ea bohlano ea Unix (June 1974), empa e batla e tšoana le e hlahileng tokollong e latelang. Maikutlo a sa tsoa kenyelletsoa, ​​kahoo o ka tlola khatiso ea bohlano.

Khatiso ea botšelela ea Unix (1975)

Ha re qale ho bala khoutu ea mohloli oa Unix khatiso ea botšelela (Motšeanong 1975). Haholo ka lebaka la litau ho bonolo haholo ho e fumana ho feta mehloli ea liphetolelo tsa pejana:

Ka lilemo tse ngata buka litau e ne e le eona feela tokomane ho Unix kernel e fumanehang kantle ho Bell Labs. Le hoja laesense ea khatiso ea botšelela e ne e lumella matichere ho sebelisa khoutu ea eona ea mohloli, laesense ea khatiso ea bosupa e ne e qhelela ka thōko monyetla ona, kahoo buka eo e ile ea ajoa ka mokhoa oa likopi tse ngotsoeng ka mongolo o seng molaong.

Kajeno o ka reka khatiso e ncha ea buka, e sekoahelo se bonts'ang baithuti mochining oa kopi. 'Me ka lebaka la Warren Toomey (ea qalileng morero oa TUHS) o ka khoasolla Faele ea PDF e nang le khoutu ea mohloli bakeng sa khatiso ea botšelela. Ke batla ho u fa leseli la hore na ho entsoe boiteko bo bokae ho theha faele:

Lilemong tse fetang 15 tse fetileng, ke ile ka thaepa kopi ea khoutu ea mohloli e fanoeng litau, hobane ke ne ke sa rate boleng ba kopi ea ka ho tsoa ho palo e sa tsejoeng ea likopi tse ling. TUHS e ne e so be teng mme ke ne ke sa khone ho fumana mehloli ea khale. Empa ka 1988, ke ile ka fumana tepi ea khale ea lipina tse 9 e nang le bekapo ho tsoa komporong ea PDP11. Ho ne ho le thata ho bolela hore na e sebetsa, empa ho ne ho e-na le sefate sa /usr/src/ seo boholo ba lifaele li neng li ngotsoe ho sona ka selemo sa 1979, seo le ka nako eo se neng se shebahala sa khale. E ne e le khatiso ea bosupa kapa e nkiloeng ho eona PWB, joalokaha ke ne ke lumela.

Ke ile ka nka se fumanoeng e le motheo mme ka hlophisa mehloli ea mehloli ho khatiso ea botšelela. Tse ling tsa khoutu li ile tsa lula li tšoana, empa tse ling li ne li tlameha ho hlophisoa hanyenyane, ho fetola letšoao la kajeno += ho ea khale =+. Lintho tse ling li ne li hlakotsoe feela, 'me tse ling li ile tsa tlameha ho ngoloa bocha, empa eseng haholo.

Mme kajeno re ka bala inthaneteng ho TUHS khoutu ea mohloli oa khatiso ea botšelela ho tsoa ho polokelong ea litaba, eo Dennis Ritchie a neng a e-na le letsoho ho eona.

Ka tsela, ha u habanya feela, tšobotsi ea mantlha ea khoutu ea C pele ho nako ea Kernighan le Ritchie ke eona. bokgutshoanyane. Ha se hangata ke khonang ho kenya likotoana tsa khoutu ntle le ho hlophisoa ho hoholo ho lekana sebaka se batlang se le moqotetsane sebakeng sa ka sa marang-rang.

Mathomong /usr/sys/ken/pipe.c ho na le tlhaloso e hlalosang (mme e, ho na le ho feta /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

Boholo ba buffer ha bo so fetohe ho tloha khatisong ea bone. Empa mona rea ​​bona, ntle le litokomane tsa sechaba, hore liphaephe li kile tsa sebelisa lifaele e le polokelo ea polokelo!

Ha e le lifaele tsa LARG, li lumellana le inode folakha LARG, e sebelisoang ke "algorithm e kholo ea aterese" ho sebetsa li-blocks tse sa tobang ho tšehetsa litsamaiso tse kholo tsa lifaele. Kaha Ken o itse ho molemo ho se li sebelise, ke tla amohela lentsoe la hae ka thabo.

Mona ke mohala oa 'nete oa sistimi 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;
}

Maikutlo a hlalosa hantle se etsahalang mona. Empa ho utloisisa khoutu ha ho bonolo haholo, karolo e 'ngoe ka lebaka la tsela "theha mosebedisi u»le diresetere R0 и R1 liparamente tsa mohala oa sistimi le litekanyetso tsa ho khutla lia fetisoa.

Ha re leke le ialloc() beha holim'a disk inode (ho sebetsana le index), le ka thuso falloc() - beha tse peli mohopolong faele. Haeba tsohle li tsamaea hantle, re tla beha lifolakha ho khetholla lifaele tsena e le lipheletsong tse peli tsa liphaephe, re li supe ho inode e le 'ngoe (eo palo ea eona ea litšupiso e tla behoa ho 2),' me u tšoaee inode hore e fetotsoe ebile e sebelisoa. Ela hloko likopo ho iput() litseleng tsa liphoso ho fokotsa palo ea litšupiso ho inode e ncha.

pipe() tlameha ho feta R0 и R1 kgutlisa dinomoro tse hlalosang faele bakeng sa ho bala le ho ngola. falloc() e khutlisetsa pointer ho sebopeho sa faele, empa hape "e khutla" ka u.u_ar0[R0] le tlhaloso ea faele. Ke hore, khoutu e boloka ho r tlhaloso ea faele bakeng sa ho bala le ho fana ka tlhaloso ea faele bakeng sa ho ngola ka ho toba ho tloha u.u_ar0[R0] ka mora mohala wa bobedi falloc().

Senya FPIPE, eo re e behileng ha re theha pipeline, e laola boitšoaro ba mosebetsi rdwr() ho sys2.cho letsetsa mekhoa e ikhethileng ea I/O:

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

Ebe mosebetsi readp() в pipe.c e bala lintlha tse tsoang ho pipeline. Empa ho molemo ho latela ts'ebetsong ho qala ho tloha writep(). Hape, khoutu e fetohile e rarahaneng haholoanyane ka lebaka la litumellano tsa ho fetisa likhang, empa lintlha tse ling li ka tlosoa.

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

Re batla ho ngola li-byte ho kenya liphaephe u.u_count. Pele re hloka ho notlela inode (sheba ka tlase plock/prele).

Ebe re hlahloba counter reference inode. Hafeela lipheletsong tse peli tsa pipeline li ntse li bulehile, counter e lokela ho lekana le 2. Re tšoara sehokelo se le seng (ho tloha rp->f_inode), kahoo haeba counter e ka tlase ho 2, e tlameha ho bolela hore mokhoa oa ho bala o koetse pheletso ea pipeline. Ka mantsoe a mang, re leka ho ngolla pipeline e koetsoeng, 'me sena ke phoso. Khoutu ea phoso ea lekhetlo la pele EPIPE le pontsho SIGPIPE e hlahile khatisong ea botšelela ea Unix.

Empa le haeba conveyor e butsoe, e kanna ea tlala. Tabeng ena, re lokolla senotlolo ebe re robala ka tšepo ea hore ts'ebetso e 'ngoe e tla bala ho tloha pipeline ebe e lokolla sebaka se lekaneng ho eona. Ha re se re tsohile, re khutlela qalong, re fanyeha senotlolo hape ebe re qala potoloho e ncha ea ho rekota.

Haeba ho na le sebaka se lekaneng sa mahala phapeng, joale re e ngolla data re sebelisa ngola(). Paramethara i_size1 ho inode (haeba pipeline e se na letho e ka lekana le 0) e bontša qetello ea data eo e seng e ntse e e-na le eona. Haeba ho na le sebaka se lekaneng sa ho rekota, re ka tlatsa pipeline ho tloha i_size1 ho PIPESIZ. Ebe re lokolla senotlolo ebe re leka ho tsosa ts'ebetso leha e le efe e emetseng ho bala ho tloha pipeline. Re khutlela qalong ho bona hore na re khonne ho ngola li-byte tse ngata kamoo re neng re hloka kateng. Haeba e hloleha, joale re qala potoloho e ncha ea ho rekota.

Hangata ke parameter i_mode inode e sebelisetsoa ho boloka tumello r, w и x. Empa tabeng ea liphaephe, re bontša hore ts'ebetso e itseng e emetse ho ngola kapa ho bala ho sebelisa likotoana IREAD и IWRITE ka ho latellana. Ts'ebetso e beha folakha le mehala sleep(), mme ho lebeletsoe hore ts'ebetso e 'ngoe nakong e tlang e tla baka wakeup().

Boselamose ba sebele bo etsahala sleep() и wakeup(). Li kengoa tšebetsong ka slp.c, mohloli oa tlhaloso e tummeng ea "Ha ua lebelloa ho utloisisa sena". Ka lehlohonolo, ha rea ​​tlameha ho utloisisa khoutu, sheba feela maikutlo a mang:

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

Mokhoa o bakang sleep() bakeng sa kanale e itseng, e ka 'na ea tsosoa hamorao ke ts'ebetso e' ngoe, e tla baka wakeup() bakeng sa kanale e tšoanang. writep() и readp() hokahanya liketso tsa bona ka mehala e joalo e tsamaisanang. lemoha hore pipe.c kamehla e etelletsa pele PPIPE ha a bitsoa sleep(), ho joalo sleep() e ka sitisoa ke lets'oao.

Hona joale re na le tsohle ho utloisisa mosebetsi 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);
}

U ka fumana ho le bonolo ho bala tšebetso ena ho tloha tlase ho ea holimo. Lekala la "bala le ho khutlisa" hangata le sebelisoa ha ho na le lintlha tse ling. Tabeng ena, re sebelisa bala() re bala boitsebiso bo bongata kamoo bo fumanehang ho qala ho tloha hona joale f_offset bala, ebe u ntlafatsa boleng ba offset e tsamaisanang le eona.

Lipalong tse latelang, phaepe e tla be e se na letho haeba sephetho sa ho bala se fihlile i_size1 ka inode. Re khutlisetsa boemo ho 0 mme re leka ho tsosa ts'ebetso leha e le efe e batlang ho ngolla pipeline. Rea tseba hore ha conveyor e tletse, writep() e tla robala ip+1. 'Me joale kaha pipeline ha e na letho, re ka e tsosa hore re qalelle potoloho ea eona ea ho ngola.

Haeba u se na letho leo u ka le balang, joale readp() e ka beha folakha IREAD le ho robala ip+2. Re tseba se tla mo tsosa writep(), ha e ngola lintlha tse ling ho pipeline.

Maikutlo ho readi() and writei() e tla u thusa ho utloisisa hore ho fapana le ho fetisa liparamente ka "u"Re ka ba tšoara joalo ka mesebetsi e tloaelehileng ea I / O e nkang faele, boemo, buffer mohopolong, le ho bala palo ea li-byte ho bala kapa ho ngola.

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

Ha e le "conservative" thibela, joale readp() и writep() thibela inode ho fihlela ba qeta mosebetsi oa bona kapa ba fumana sephetho (ke hore, call wakeup). plock() и prele() sebetsa habonolo: ho sebelisa mefuta e fapaneng ea mehala sleep и wakeup re lumelle ho tsosa ts'ebetso efe kapa efe e hlokang senotlolo seo re sa tsoa se lokolla:

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

Qalong ke ne ke sa utloisise hore na ke hobane'ng readp() ha e bake prele(ip) pele ho pitso wakeup(ip+1). Ntho ea pele ke writep() e bakang potolohong ea eona, sena plock(ip), e lebisang ho deadlock haeba readp() ha ke so tlose boloko ba ka, kahoo ka tsela e itseng khoutu e tlameha ho sebetsa ka nepo. Haeba u sheba wakeup(), joale hoa hlaka hore e tšoaea feela mokhoa oa ho robala o loketse ho phethahatsa, e le hore nakong e tlang sched() e hlile e e thakgotse. Kahoo readp() lisosa wakeup(), e tlosa senotlolo, e beha IREAD le mehala sleep(ip+2)- tsena tsohle pele writep() e tsosolosa potoloho.

Sena se phethela tlhaloso ea li-conveyors khatisong ea botšelela. Khoutu e bonolo, litlamorao tse fihlang hole.

Khatiso ea bosupa ea Unix (Pherekhong 1979) e bile tokollo e ncha e kholo (lilemo tse 'ne hamorao) e ileng ea hlahisa lits'ebetso tse ngata tse ncha le likarolo tsa kernel. E boetse e bile le liphetoho tse kholo mabapi le ts'ebeliso ea mofuta oa ho lahla, mekhatlo ea basebetsi le lisupa tse tlantsoeng ho meaho. Leha ho le joalo khoutu ea conveyor e batlang e sa fetohe. Re ka tlola khatiso ena.

Xv6, kernel e bonolo e kang ea Unix

Ho theha kernel Xv6 e susumelitsoe ke khatiso ea botšelela ea Unix, empa e ngotsoe ka sejoale-joale C ho sebetsa ho li-processor tsa x86. Khoutu e bonolo ho bala le ho utloisisoa. Hape, ho fapana le mehloli ea Unix e nang le TUHS, u ka e bokella, ua e fetola, 'me ua e tsamaisa ho hong ntle le PDP 11/70. Ka hona, kernel ena e sebelisoa haholo liunivesithing e le lisebelisoa tsa thuto mabapi le lits'ebetso tsa ts'ebetso. Mehloli li ho Github.

Khoutu e na le ts'ebetsong e hlakileng le e nahanang pipe.c, e tšehelitsoe ke buffer mohopolong sebakeng sa inode ho disk. Mona ke fana ka tlhaloso feela ea "peipi ea mohaho" le mosebetsi 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() e beha boemo ba ts'ebetsong e setseng, e kenyeletsang mesebetsi piperead(), pipewrite() и pipeclose(). Pitso ea 'nete ea sistimi sys_pipe ke wrapper kenngwa tshebetsong sysfile.c. Ke khothaletsa ho bala khoutu eohle ea hae. Ho rarahana ho boemong ba khoutu ea mohloli oa khatiso ea botšelela, empa ho bonolo haholo ebile ho monate ho bala.

Linux 0.01

Linux 0.01 khoutu ea mohloli e ka fumanoa. E tla ba e rutang ho ithuta ho kenngwa tshebetsong ha lipeipi hae fs/pipe.c. Sena se sebelisa inode ho emela pipeline, empa pipeline ka boeona e ngotsoe ka mokhoa oa morao-rao oa C. Haeba u sebelitse ka mokhoa oa hau ka har'a khoutu ea khatiso ea 6, u ke ke ua ba le bothata mona. Sena ke kamoo mosebetsi o shebahalang kateng 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;
}

Ntle le ho sheba litlhaloso tsa sebopeho, o ka fumana hore na palo ea litšupiso tsa inode e sebelisoa joang ho bona hore na ts'ebetso ea ho ngola e fella ka eng. SIGPIPE. Ntle le ho sebetsa ka-byte-byte, ts'ebetso ena e bonolo ho bapisa le mehopolo e hlalositsoeng ka holimo. Leha e le logic sleep_on/wake_up ha e shebahale e le osele.

Lithako tsa sejoale-joale tsa Linux, FreeBSD, NetBSD, OpenBSD

Ka potlako ke ile ka matha har'a lithollo tse ling tsa sejoale-joale. Ha ho le ea mong oa bona ea nang le ts'ebetsong ea disk (ha ho makatse). Linux e na le ts'ebetsong ea eona. Leha lithollo tse tharo tsa sejoale-joale tsa BSD li na le ts'ebetsong e ipapisitseng le khoutu e ngotsoeng ke John Dyson, ho theosa le lilemo li fetohile tse fapaneng haholo ho tse ling.

Ho bala fs/pipe.c (ho Linux) kapa sys/kern/sys_pipe.c (ho * BSD), ho hloka boinehelo ba 'nete. Khoutu ea kajeno e mabapi le ts'ebetso le ts'ehetso ea likarolo tse joalo ka vector le I/O ea asynchronous. 'Me lintlha tsa kabo ea memori, linotlolo le tlhophiso ea kernel kaofela li fapana haholo. Sena ha se seo likoleche li se hlokang bakeng sa thupelo ea litsamaiso tsa tšebetso.

Leha ho le joalo, ke ne ke thahasella ho cheka mekhoa ea khale (joaloka ho hlahisa SIGPIPE le ho khutla EPIPE ha u ngolla liphaephe tse koetsoeng) lithakong tsena tsohle tse fapaneng tsa sejoale-joale. Mohlomong nke ke ka bona k'homphieutha ea PDP-11 bophelong ba sebele, empa ho ntse ho e-na le lintho tse ngata tseo nka ithutang tsona ho tsoa ho khoutu e ngotsoeng lilemo pele ke hlaha.

Sengoliloeng se ngotsoeng ke Divi Kapoor ka 2011:Linux Kernel Ts'ebetsong ea Liphaephe le FIFOs" e fana ka kakaretso ea hore na liphaephe (tse ntse) li sebetsa joang Linux. A boitlamo ba morao-rao ho Linux e bonts'a mohlala oa lipeipi oa ho sebelisana, oo bokhoni ba oona bo fetang ba lifaele tsa nakoana; hape e bonts'a hore na liphaephe li tsoa hole hakae ho tloha "ho notlela ka mokhoa o hlokolosi" oa khatiso ea botšelela ea Unix kernel.

Source: www.habr.com

Eketsa ka tlhaloso