Nkhaniyi ikufotokoza kukhazikitsidwa kwa mapaipi mu Unix kernel. Ndinakhumudwa pang'ono ndi nkhani yaposachedwa yamutu wakuti "
Kodi tikukamba za chiyani?
Mapaipi, "mwina chinthu chofunikira kwambiri ku Unix," ndi chizindikiritso cha filosofi ya Unix yolumikiza mapulogalamu ang'onoang'ono pamodzi, komanso chizindikiro chodziwika pamzere wolamula:
$ echo hello | wc -c
6
Kuchita uku kumatengera kuyimba komwe kumaperekedwa ndi kernel pipe
, zomwe zafotokozedwa pamasamba olembedwa
Mapaipi amapereka njira imodzi yokha yolumikizirana. Chitolirocho chimakhala ndi zolowetsa (lemba kumapeto) ndi zotuluka (werengani kumapeto). Deta yolembedwa polowetsa payipi imatha kuwerengedwa pazotulutsa.
Njirayi imapangidwa pogwiritsa ntchito kuyimba
pipe(2)
, yomwe imabweretsanso zofotokozera ziwiri za fayilo: imodzi ikunena za kulowetsa kwa payipi, yachiwiri ku zotsatira zake.
Zomwe zimatuluka kuchokera ku lamulo ili pamwambazi zikuwonetsa kupangidwa kwa payipi ndi kutuluka kwa deta kudzera mu njira imodzi kupita ku ina:
$ 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
Njira ya makolo imayimba pipe()
kuti mupeze zofotokozera za fayilo. Njira imodzi ya mwana imalembera ku chogwirira chimodzi, ndipo njira ina imawerengera zomwezo kuchokera ku chogwirira china. Chipolopolocho chimagwiritsa ntchito dup2 "kutchulanso" zofotokozera 3 ndi 4 kuti zigwirizane ndi stdin ndi stdout.
Popanda mapaipi, chipolopolocho chiyenera kulemba zotsatira za ndondomeko imodzi ku fayilo ndikuyipereka ku ndondomeko ina kuti muwerenge zomwe zili mu fayilo. Zotsatira zake, titha kutaya zinthu zambiri komanso malo a disk. Komabe, mapaipi ndi abwino osati chifukwa amakulolani kupewa kugwiritsa ntchito mafayilo osakhalitsa:
Ngati ndondomeko ikuyesera kuwerenga kuchokera paipi yopanda kanthu ndiye
read(2)
adzatsekereza mpaka deta ipezeke. Ngati ndondomeko ikuyesera kulembera payipi yonse, ndiyewrite(2)
adzatsekereza mpaka deta yokwanira yawerengedwa kuchokera paipi kuti ilembe.
Monga chofunikira cha POSIX, ichi ndi chinthu chofunikira: kulembera mapaipi mpaka PIPE_BUF
ma byte (osachepera 512) ayenera kukhala atomiki kuti njira zizitha kulumikizana wina ndi mnzake kudzera papaipi momwe mafayilo okhazikika (omwe sapereka zitsimikizo) sangathe.
Mukamagwiritsa ntchito fayilo yokhazikika, njira imatha kulemba zonse zomwe zatulutsidwa ndikuzipereka kunjira ina. Kapena njira zimatha kugwira ntchito mofanana kwambiri, pogwiritsa ntchito njira yowonetsera kunja (monga semaphore) kuti azidziwitsana pamene kulemba kapena kuwerenga kwatha. Ma conveyor amatipulumutsa ku zovuta zonsezi.
Kodi tikuyang'ana chiyani?
Ndikufotokozerani m'mawu osavuta kuti zikhale zosavuta kuti muganizire momwe conveyor angagwire ntchito. Muyenera kugawa buffer ndi malo ena kukumbukira. Mudzafunika ntchito kuti muwonjezere ndi kuchotsa deta mu buffer. Mudzafunika njira zina zoyimbira ntchito panthawi yowerenga ndi kulemba pamafayilo ofotokozera. Ndipo mudzafunika maloko kuti mugwiritse ntchito njira yapadera yomwe tafotokozayi.
Tsopano ndife okonzeka kufunsa kachidindo kochokera ku kernel pansi pa nyali yowala kuti titsimikizire kapena kutsutsa chitsanzo chathu chosamveka bwino chamalingaliro. Koma nthawi zonse khalani okonzeka kukumana ndi zomwe simukuziyembekezera.
Tikuyang'ana kuti?
Sindikudziwa komwe buku langa lodziwika bwino liri "
Kuyendayenda m'malo osungiramo zakale a TUHS kuli ngati kuyendera nyumba yosungiramo zinthu zakale. Titha kuyang'ana mbiri yathu yomwe tagawana, ndipo ndikulemekeza zaka zambiri zoyesayesa kuti ndipezenso zinthu zonsezi pang'onopang'ono kuchokera pamatepi akale ndi zisindikizo. Ndipo ndikudziwa bwino za zidutswa zomwe zikusowabe.
Popeza takhutitsa chidwi chathu chofuna kudziwa mbiri yakale ya ma conveyor, titha kuyang'ana maso amakono kuti tiyerekeze.
Mwa njira, pipe
ndi system call number 42 patebulo sysent[]
. Mwangozi?
Nkhokwe Zachikhalidwe za Unix (1970-1974)
Sindinapeze zotsatila pipe(2)
ngakhale mu
TUHS ikunena kuti
Unix 1973rd Edition inali mtundu womaliza wokhala ndi kernel yolembedwa m'chilankhulo cha msonkhano, komanso mtundu woyamba wokhala ndi mapaipi. M'chaka cha XNUMX, ntchito yokonza kope lachitatu lidachitika, kernel inalembedwanso mu C, ndipo kope lachinayi la Unix linawonekera.
Wowerenga wina adapeza jambulani chikalata chomwe Doug McIlroy adapereka lingaliro la "kulumikiza mapulogalamu ngati payipi yamunda."
M'buku la Brian Kernighan
Unix itatuluka, chidwi changa ndi ma coroutines chinandichititsa kufunsa wolemba OS, Ken Thompson, kuti alole deta yolembedwa ku ndondomeko kuti ipite osati ku chipangizo chokha, komanso kuti itulutse njira ina. Ken anaganiza kuti nβzotheka. Komabe, monga minimalist, adafuna kuti machitidwe aliwonse azigwira ntchito yayikulu. Kodi kulemba mwachindunji pakati pa njira ndi mwayi waukulu polembera fayilo yapakatikati? Ndipamene ndinapanga lingaliro lachindunji ndi dzina lochititsa chidwi la "paipi" ndi kufotokoza kwa mawu ogwirizana pakati pa njira zomwe Ken potsiriza anafuula kuti: "Ndichita!"
Ndipo anatero. Usiku wina watsoka, Ken anasintha kernel ndi chipolopolo, anakonza mapulogalamu angapo okhazikika kuti agwirizane ndi momwe amavomerezera kulowetsa (zomwe zingabwere kuchokera ku pipeline), komanso kusintha mayina a mafayilo. Tsiku lotsatira, mapaipi anayamba kugwiritsidwa ntchito mofala kwambiri pa ntchito. Pofika kumapeto kwa mlunguwo, alembi anali kuwagwiritsa ntchito potumiza zikalata kuchokera ku makina osindikizira mawu kupita ku makina osindikizira. Patapita nthawi, Ken anasintha API ndi syntax yoyambirira kuti atseke kugwiritsa ntchito mapaipi ndi misonkhano yoyeretsa, yomwe yakhala ikugwiritsidwa ntchito kuyambira pamenepo.
Tsoka ilo, code code ya mtundu wachitatu wa Unix kernel yatayika. Ndipo ngakhale tili ndi kernel source code yolembedwa mu C
Tili ndi zolemba za pipe(2)
kuchokera ku zotulutsidwa zonse ziwiri, kotero mutha kuyamba ndikusaka zolembazo pipe(2)
imalembedwa m'chinenero chophatikizira ndipo imabweretsanso fayilo imodzi yokha yofotokozera, koma imapereka kale zofunikira zomwe zikuyembekezeredwa:
Kuitana kwadongosolo chitoliro imapanga njira yolowera/zotulutsa yotchedwa pipeline. Mafotokozedwe a fayilo omwe abwezedwa angagwiritsidwe ntchito powerenga ndi kulemba. Chinachake chikalembedwa pamapaipi, mpaka ma byte 504 a data amasungidwa, kenako ntchito yolemba imayimitsidwa. Powerenga paipi, deta yosungidwa imachotsedwa.
Pofika chaka chotsatira kernel inali italembedwanso mu C, ndipo pipe(fildes)
Β»:
Kuitana kwadongosolo chitoliro imapanga njira yolowera/zotulutsa yotchedwa pipeline. Zofotokozera za fayilo zomwe zabwezedwa zitha kugwiritsidwa ntchito powerenga ndi kulemba. Chinachake chikalembedwa ku payipi, chogwiririra chomwe chabwezedwa mu r1 (resp. fildes[1]) chimagwiritsidwa ntchito, chosungidwa mpaka ma 4096 bytes a data, pambuyo pake kulembako kuyimitsidwa. Powerenga kuchokera papaipi, chogwiriracho chinabwerera ku r0 (resp. fildes[0]) chimatenga deta.
Zimaganiziridwa kuti payipi ikafotokozedwa, njira ziwiri (kapena zochulukirapo) zoyankhulirana (zopangidwa ndi kuyitana kotsatira Foloko) adzasamutsa deta kuchokera paipiyo pogwiritsa ntchito mafoni werengani ΠΈ kulemba.
Chigobacho chili ndi mawu ofotokozera mizere yolumikizana ndi mapaipi.
Mafoni oti muwerenge kuchokera papaipi yopanda kanthu (yopanda deta yosungidwa) yomwe ili ndi mapeto amodzi (zofotokozera zonse zolembera zatsekedwa) bweretsani "mapeto a fayilo". Maitanidwe olembera mumkhalidwe wofananawo amanyalanyazidwa.
Poyamba
Kusindikiza kwachisanu ndi chimodzi kwa Unix (1975)
Tiyeni tiyambe kuwerenga Unix source code
Kwa zaka zambiri bukuli Mikango chinali chikalata chokhacho pa Unix kernel yomwe ikupezeka kunja kwa Bell Labs. Ngakhale kuti laisensi ya kope lachisanu ndi chimodzi inalola aphunzitsi kugwiritsira ntchito code code yake, laisensi ya kope lachisanu ndi chiwiri silinaphatikizepo zimenezi, motero bukulo linagaΕ΅iridwa mβmakope olembedwa mwachisawawa.
Lero mutha kugula kusindikizidwanso kwa bukhuli, chikuto chake chomwe chikuwonetsa ophunzira pamakina amakope. Ndipo chifukwa cha Warren Toomey (yemwe adayambitsa pulojekiti ya TUHS) mutha kutsitsa
Zaka zoposa 15 zapitazo, ndinalemba kopi ya code code yomwe inaperekedwa Mikango, chifukwa sindinakonde mtundu wa kope langa kuchokera ku nambala yosadziwika ya makope ena. TUHS panalibe pano ndipo ndinalibe mwayi wopeza magwero akale. Koma mu 1988, ndinapeza tepi yakale ya 9-track yomwe inali ndi zosunga zobwezeretsera kuchokera pa kompyuta ya PDP11. Zinali zovuta kudziwa ngati zikugwira ntchito, koma panali mtengo / usr / src/ mtengo womwe mafayilo ambiri adalembedwa ndi chaka cha 1979, chomwe chinkawoneka ngati chakale. Linali kope lachisanu ndi chiwiri kapena lochokera ku PWB, monga ndimakhulupirira.
Ndinatenga zopezazo ngati maziko ndikusintha pamanja magwero a kope lachisanu ndi chimodzi. Ma code ena adakhalabe ofanana, koma ena adayenera kusinthidwa pang'ono, kusintha chizindikiro chamakono += kukhala chachikale =+. Zinthu zina zidangochotsedwa, ndipo zina zidayenera kulembedwanso, koma osati mochulukira.
Ndipo lero titha kuwerenga pa intaneti pa TUHS code source ya kope lachisanu ndi chimodzi kuchokera
Mwa njira, poyang'ana koyamba, mbali yayikulu ya C-code isanafike nthawi ya Kernighan ndi Ritchie ndi yake. mwachidule. Sikuti nthawi zambiri ndimatha kuyika zidutswa za code popanda kusintha kwambiri kuti zigwirizane ndi malo ocheperako patsamba langa.
Kumayambiriro
/*
* 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
Kukula kwa bafa sikunasinthe kuyambira kusindikiza kwachinayi. Koma apa tikuwona, popanda zolemba zapagulu, kuti mapaipi adagwiritsapo ntchito mafayilo ngati zosunga zobwezeretsera!
Ponena za mafayilo a LARG, amafanana ndi
Nayi kuyimba kwadongosolo kwenikweni 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;
}
Ndemangayi ikufotokoza momveka bwino zomwe zikuchitika pano. Koma kumvetsetsa kachidindo sikophweka, mwa zina chifukwa cha njira "R0
ΠΈ R1
ma parameters oyimba dongosolo ndi zobwerera zimadutsa.
Tiyeni tiyese ndi
pipe()
ayenera kudutsa R0
ΠΈ R1
bweretsani manambala ofotokozera mafayilo kuti muwerenge ndi kulemba. falloc()
imabweretsanso cholozera pamafayilo, komanso "kubwerera" kudzera u.u_ar0[R0]
ndi fayilo yofotokozera. Ndiye kuti, code imasunga mkati r
chofotokozera fayilo kuti muwerenge ndikugawa fayilo yofotokozera kuti mulembe mwachindunji kuchokera u.u_ar0[R0]
itayitananso kachiwiri falloc()
.
Sakanizani FPIPE
, zomwe timayika popanga payipi, zimayendetsa khalidwe la ntchitoyo
/*
* 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);
}
/* β¦ */
}
Ndiye ntchito readp()
Π² pipe.c
amawerenga deta kuchokera ku pipeline. Koma ndi bwino kutsatira ndondomeko kuyambira pachiyambi writep()
. Apanso, codeyo yakhala yovuta kwambiri chifukwa cha mikangano yodutsana, koma zina zikhoza kuchotsedwa.
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;
}
Tikufuna kulemba ma byte kuti alowetse mapaipi u.u_count
. Choyamba tiyenera kutseka inode (onani pansipa plock
/prele
).
Kenako timayang'ana kauntala ya inode. Malingana ngati malekezero onse a payipi amakhala otseguka, kauntala iyenera kukhala yofanana ndi 2. Timagwira ulalo umodzi (kuchokera rp->f_inode
), kotero ngati kauntala ndi yocheperapo 2, ziyenera kutanthauza kuti ndondomeko yowerengera yatseka mapeto ake a payipi. Mwa kuyankhula kwina, tikuyesera kulembera payipi yotsekedwa, ndipo izi ndi zolakwika. Kodi yolakwika koyamba EPIPE
ndi chizindikiro SIGPIPE
adawonekera mu kope lachisanu ndi chimodzi la Unix.
Koma ngakhale chotengeracho chili chotsegula, chikhoza kukhala chodzaza. Pankhaniyi, timamasula loko ndikupita kukagona ndi chiyembekezo kuti njira ina idzawerenga paipi ndikumasula malo okwanira mmenemo. Titadzuka, timabwerera koyambira, ndikuyikanso loko ndikuyamba kujambula kwatsopano.
Ngati pali malo okwanira aulere mu payipi, ndiye timalemba deta kwa izo pogwiritsa ntchito i_size1
pa inode (ngati payipi ilibe kanthu ikhoza kukhala yofanana ndi 0) imasonyeza kutha kwa deta yomwe ili nayo kale. Ngati pali malo okwanira kujambula, tikhoza kudzaza payipi kuchokera i_size1
mpaka PIPESIZ
. Kenako timamasula loko ndikuyesera kudzutsa njira iliyonse yomwe ikuyembekezera kuwerenga kuchokera paipi. Timabwereranso kumayambiriro kuti tiwone ngati tinatha kulemba ma byte ambiri momwe timafunikira. Ngati sichikanika, ndiye kuti timayamba kujambula kwatsopano.
Kawirikawiri parameter i_mode
inode imagwiritsidwa ntchito kusunga zilolezo r
, w
ΠΈ x
. Koma pankhani ya mapaipi, timawonetsa kuti njira ina ikudikirira kulemba kapena kuwerenga pogwiritsa ntchito ma bits IREAD
ΠΈ IWRITE
motsatana. Njirayi imayika mbendera ndi kuyitana sleep()
, ndipo zikuyembekezeredwa kuti njira ina mtsogolo idzayambitsa wakeup()
.
Matsenga enieni amachitika mkati sleep()
ΠΈ wakeup()
. Amakhazikitsidwa mu
/*
* 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) /* β¦ */
Njira zomwe zimayambitsa sleep()
pa njira inayake, ikhoza kudzutsidwa pambuyo pake ndi njira ina, yomwe ingayambitse wakeup()
pa njira yomweyo. writep()
ΠΈ readp()
kugwirizanitsa zochita zawo kudzera mu mafoni awiriwa. Zindikirani kuti pipe.c
nthawi zonse amaika patsogolo PPIPE
ataitanidwa sleep()
, ndi choncho sleep()
akhoza kusokonezedwa ndi chizindikiro.
Tsopano tili ndi zonse kuti timvetsetse ntchitoyi 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);
}
Mutha kupeza mosavuta kuwerenga ntchitoyi kuchokera pansi mpaka pamwamba. Nthambi ya "kuwerenga ndi kubwerera" nthawi zambiri imagwiritsidwa ntchito ngati pali data paipi. Pankhaniyi, ife ntchito f_offset
kuwerenga, ndiyeno sinthani mtengo wofananira nawo.
Pakuwerenga kotsatira, payipi idzakhala yopanda kanthu ngati zowerengera zafika i_size1
ku inode. Timakhazikitsanso malo ku 0 ndikuyesera kudzutsa njira iliyonse yomwe ikufuna kulembera mapaipi. Tikudziwa kuti conveyor ikadzadza. writep()
adzagona tulo ip+1
. Ndipo tsopano payipi ilibe, titha kuidzutsa kuti tiyambirenso kulemba.
Ngati mulibe chowerenga, ndiye readp()
akhoza kuika mbendera IREAD
ndi kugona tulo ip+2
. Tikudziwa zomwe zidzamudzutse writep()
, pamene ikulemba deta ku pipeline.
Ndemanga kwa u
"Titha kuwatenga ngati ntchito zanthawi zonse za I / O zomwe zimatenga fayilo, malo, chosungira kukumbukira, ndikuwerengera kuchuluka kwa ma byte oti muwerenge kapena kulemba.
/*
* 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;
/* β¦ */
Ponena za kutsekereza kwa "Conservative", ndiye readp()
ΠΈ writep()
letsani inode mpaka atamaliza ntchito yawo kapena kulandira zotsatira (ndiko kuti, kuyimba wakeup
). plock()
ΠΈ prele()
imagwira ntchito mophweka: kugwiritsa ntchito mafoni osiyanasiyana sleep
ΠΈ wakeup
tiloleni kudzutsa njira iliyonse yomwe ikufunika loko yomwe tangotulutsa kumene:
/*
* 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);
}
}
Poyamba sindinkamvetsa chifukwa chake readp()
sichimayambitsa prele(ip)
asanayambe kuyitana wakeup(ip+1)
. Chinthu choyamba ndi writep()
zimayambitsa mkombero wake, izi plock(ip)
, zomwe zimatsogolera ku deadlock ngati readp()
sindinachotse chipika changa, ndiye mwanjira ina code iyenera kugwira ntchito moyenera. Ngati muyang'ana wakeup()
, ndiye zikuwonekeratu kuti zimangowonetsa njira yogona ngati yokonzeka kuphedwa, kotero kuti m'tsogolomu sched()
anayambitsadi. Choncho readp()
zoyambitsa wakeup()
, amachotsa loko, amaika IREAD
ndi mafoni sleep(ip+2)
- zonsezi kale writep()
ikuyambiranso kuzungulira.
Izi zikumaliza kufotokoza za zotengera m'kope lachisanu ndi chimodzi. Code yosavuta, zotsatira zofika patali.
Xv6, kernel yosavuta ngati Unix
Kupanga kernel
Code ili ndi kukhazikitsa momveka bwino komanso moganizira 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()
amakhazikitsa dziko lonse la kukhazikitsidwa, lomwe limaphatikizapo ntchito piperead()
, pipewrite()
ΠΈ pipeclose()
. Kuitana kwenikweni kwadongosolo sys_pipe
ndi wrapper yokhazikitsidwa mkati
Linux 0.01
Linux 0.01 source code ikupezeka. Zidzakhala zophunzitsa kuphunzira kukhazikitsa mapaipi ake fs
/pipe.c
. Izi zimagwiritsa ntchito inode kuyimira mapaipi, koma payipi yokhayo imalembedwa mu C yamakono. Ngati mwadutsa khodi ya 6th edition, mulibe vuto pano. Izi ndi momwe ntchitoyi ikuwonekera 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;
}
Popanda kuyang'ananso matanthauzidwe ake, mutha kudziwa momwe mawerengedwe a inode amagwiritsidwira ntchito kuti muwone ngati ntchito yolemba imabweretsa SIGPIPE
. Kuphatikiza pa kugwira ntchito byte-byte, ntchitoyi ndi yosavuta kufananiza ndi malingaliro omwe tafotokozawa. Ngakhale logic sleep_on
/wake_up
sizikuwoneka zachilendo.
Zingwe zamakono za Linux, FreeBSD, NetBSD, OpenBSD
Mwamsanga ndinadutsa maso amakono. Palibe aliyense wa iwo amene ali ndi kukhazikitsa kwa disk (zosadabwitsa). Linux ili ndi kukhazikitsa kwake. Ngakhale ma kernel atatu amakono a BSD ali ndi kukhazikitsa kutengera ma code omwe adalembedwa ndi John Dyson, pazaka zambiri akhala osiyana kwambiri wina ndi mnzake.
Kuwerenga fs
/pipe.c
(pa Linux) kapena sys
/kern
/sys_pipe.c
(pa * BSD), pamafunika kudzipereka kwenikweni. Khodi yamasiku ano ikukhudza magwiridwe antchito ndi kuthandizira pazinthu monga vekitala ndi asynchronous I/O. Ndipo tsatanetsatane wa kagawidwe ka kukumbukira, maloko ndi kasinthidwe ka kernel zimasiyana kwambiri. Izi sizomwe makoleji amafunikira pamaphunziro oyambira ogwiritsira ntchito.
Komabe, ndinali ndi chidwi chofuna kukumba machitidwe akale (monga kupanga SIGPIPE
ndi kubwerera EPIPE
polembera mapaipi otsekedwa) m'maso onse amakono osiyanasiyana. Mwina sindidzawona kompyuta ya PDP-11 m'moyo weniweni, koma pali zambiri zoti ndiphunzire kuchokera ku code yomwe inalembedwa zaka zambiri ndisanabadwe.
Nkhani yolembedwa ndi Divi Kapoor mu 2011:
Source: www.habr.com