Edemede a na-akọwa mmejuputa pipeline na kernel Unix. Enwere m nkụda mmụọ na otu akụkọ na nso nso a nke isiokwu ya bụ "
Kedu ihe anyị na-ekwu?
Pipeline, "ma eleghị anya, ihe kachasị mkpa mepụtara na Unix," bụ njirimara na-akọwapụta nkà ihe ọmụma Unix dị n'okpuru nke ijikọta obere mmemme ọnụ, yana akara ama ama na ahịrị iwu:
$ echo hello | wc -c
6
Ọrụ a dabere na oku sistemu kernel nyere pipe
, nke a kọwara na ibe akwụkwọ
Pipeline na-enye ọwa unidirectional maka nkwurịta okwu interprocess. Pipeline nwere ntinye (njedebe dee) na mmepụta (ngwụcha agụ). Enwere ike ịgụ data edere na ntinye nke pipeline na mmepụta.
A na-emepụta ọkpọkọ site na iji oku
pipe(2)
, nke na-eweghachi ihe ndekọ faịlụ abụọ: otu na-ezo aka na ntinye nke pipeline, nke abụọ na mmepụta.
Nsonaazụ nsonaazụ sitere na iwu dị n'elu na-egosi okike nke pipeline na ntinye data site na ya site n'otu usoro gaa na nke ọzọ:
$ 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
Usoro nne na nna na-akpọ pipe()
iji nweta ndị na-akọwa faịlụ agbakwunyere. Otu usoro nwatakịrị na-ede n'otu aka, usoro ọzọ na-agụkwa otu data site na aka ọzọ. Shei ahụ na-eji dup2 mee ka “nyegharịa aha” nkọwa 3 na 4 iji kwekọọ stdin na stdout.
Enweghị ọkpọkọ, shei ahụ ga-edepụta mmepụta nke otu usoro na faịlụ ma nyefee ya na usoro ọzọ iji gụọ data sitere na faịlụ ahụ. N'ihi ya, anyị ga-emefusị ihe onwunwe na ohere diski. Otú ọ dị, pipeline dị mma ọ bụghị nanị n'ihi na ha na-enye gị ohere izere iji faịlụ nwa oge:
Ọ bụrụ na usoro na-agbalị ịgụ site na pipeline efu mgbe ahụ
read(2)
ga-egbochi ruo mgbe data ga-adị. Ọ bụrụ na usoro na-agbalị ịdegara pipeline zuru ezu, mgbe ahụwrite(2)
ga-egbochi ruo mgbe agụchara data zuru oke site na pipeline iji dee ya.
Dị ka POSIX chọrọ, nke a bụ ihe dị mkpa: na-ede na pipeline ruo PIPE_BUF
bytes (opekata mpe 512) ga-abụrịrị atomic ka usoro wee nwee ike ịkparịta ụka n'etiti ibe ha site na pipeline n'ụzọ faịlụ mgbe niile (nke na-enyeghị nkwa dị otú ahụ) enweghị ike.
Mgbe ị na-eji faịlụ oge niile, usoro nwere ike idepụta ihe niile na ya ma nyefee ya na usoro ọzọ. Ma ọ bụ usoro nwere ike ịrụ ọrụ n'ụdị ihe yiri ya nke ukwuu, na-eji usoro nrịbama mpụga (dị ka semaphore) iji mee ka ibe ha mara mgbe ederede ma ọ bụ gụchara. Ndị na-ebufe na-azọpụta anyị na nsogbu a niile.
Kedu ihe anyị na-achọ?
M ga-akọwa ya n'ụzọ dị mfe ka ọ dịrị gị mfe iche n'echiche ka ebufe nwere ike isi rụọ ọrụ. Ị ga-achọ ikenye ihe nchekwa na ụfọdụ steeti na ebe nchekwa. Ị ga-achọ ọrụ iji gbakwunye na wepụ data na nchekwa. Ị ga-achọ ụzọ ụfọdụ iji kpọọ ọrụ n'oge a na-agụ na ide ọrụ na nkọwa faịlụ. Na ị ga-achọ mkpọchi iji mejuputa omume pụrụ iche akọwara n'elu.
Ugbu a, anyị adịla njikere ịjụ koodu isi mmalite kernel n'okpuru oriọna na-egbuke egbuke iji kwado ma ọ bụ gọnarị ụdị echiche anyị na-edoghị anya. Ma na-adị njikere mgbe niile maka ihe a na-atụghị anya ya.
Ebee ka anyị na-achọ?
Amaghị m ebe akwụkwọ akụkọ a ma ama dị "
Ịgagharị na ebe nchekwa TUHS dị ka ịga ụlọ ngosi ihe mgbe ochie. Anyị nwere ike ileba anya n'akụkọ ihe mere eme anyị na-ekekọrịta, enwere m nkwanye ùgwù maka mgbalị ọtụtụ afọ agbagoro iji weghachi ihe a niile ntakịrị ntakịrị site na teepu na mbipụta ochie. Amakwa m nke ọma iberibe iberibe ihe ndị ahụ ka na-efu.
N'ịbụ onye mejuworo ọchịchọ anyị nwere banyere akụkọ ihe mere eme ochie nke ndị na-ebufe ebu, anyị nwere ike ileba anya n'ọgbọ a maka ntụnyere.
Site n'ụzọ, pipe
bụ oku usoro nọmba 42 na tebụl sysent[]
. Ọ dabara?
Ọdịnala Unix kernel (1970–1974)
Ahụghị m akara ọ bụla pipe(2)
ọbụghị na
TUHS kwuru na
Unix 1973rd Edition bụ ụdị ikpeazụ nwere kernel edere n'asụsụ mgbakọ, mana ọ bụkwa ụdị nke mbụ nwere pipeline. N'ime XNUMX, a rụrụ ọrụ iji melite mbipụta nke atọ, e degharịrị kernel na C, ya mere mbipụta nke anọ nke Unix pụtara.
Otu onye na-agụ hụrụ nyocha nke akwụkwọ nke Doug McIlroy tụpụtara echiche nke "ijikọ mmemme dị ka eriri ubi."
N'akwụkwọ Brian Kernighan
Mgbe Unix pụtara, mmasị m nwere na coroutines mere ka m jụọ onye odee OS, Ken Thompson, ka o kwe ka data edere na usoro ka ọ bụghị naanị na ngwaọrụ ahụ, kamakwa ịmepụta na usoro ọzọ. Ken kpebiri na ọ ga-ekwe omume. Otú ọ dị, dị ka minimalist, ọ chọrọ ka usoro ọ bụla na-arụ ọrụ na-arụ ọrụ dị mkpa. Ide ihe ozugbo n'etiti usoro ọ bụ nnukwu uru karịa ide na faịlụ etiti? Ọ bụ naanị mgbe m mere atụmatụ a kapịrị ọnụ nke nwere aha na-adọrọ adọrọ "payline" na nkọwa nke syntax maka mmekọrịta n'etiti usoro ka Ken mechara kwuo, sị: "M ga-eme ya!"
Ma mee ya. Otu mgbede dị egwu, Ken gbanwere kernel na shei, dozie ọtụtụ mmemme ọkọlọtọ iji hazie ka ha si anabata ntinye (nke nwere ike isi na pipeline), ma gbanwee aha faịlụ. N'echi ya, a malitere iji pipeline eme ihe na ngwa ngwa. Ka ọ na-erule ngwụsị izu, ndị odeakwụkwọ na-eji ha ezipụ akwụkwọ sitere na ndị na-emepụta okwu na ndị na-ebi akwụkwọ. Obere oge ka e mesịrị, Ken dochie API mbụ na syntax maka iji ọkpọkọ eme ihe na mgbakọ dị ọcha, bụ nke e jiworo mee ihe kemgbe ahụ.
N'ụzọ dị mwute, koodu isi mmalite maka mbipụta Unix kernel nke atọ efuola. Na agbanyeghị na anyị nwere koodu isi mmalite kernel edere na C
Anyị nwere akwụkwọ ederede maka pipe(2)
site na ntọhapụ abụọ ahụ, yabụ ị nwere ike ịmalite site na ịchọ akwụkwọ ahụ pipe(2)
edere ya n'asụsụ mgbakọ wee weghachi naanị otu nkọwa faịlụ, mana enyelarị ọrụ isi a tụrụ anya ya:
Oku sistemu ọkpọkọ na-emepụta usoro ntinye/mpụta nke a na-akpọ pipeline. Enwere ike iji nkọwa faịlụ eweghachitere maka ịrụ ọrụ ọgụgụ na ide. Mgbe edere ihe na pipeline, a na-echekwa ihe ruru 504 bytes nke data, mgbe nke ahụ gasịrị, a kwụsịrị usoro ide ihe. Mgbe ị na-agụ site na pipeline, a na-ewepụ data echekwara.
Ka ọ na-erule afọ na-esote kernel ahụ edegharịrị na C, na pipe(fildes)
»:
Oku sistemu ọkpọkọ na-emepụta usoro ntinye/mpụta nke a na-akpọ pipeline. Enwere ike iji nkọwa faịlụ eweghachite n'ọrụ ịgụ na ide. Mgbe a na-ede ihe na pipeline, a na-eji aka ahụ laghachi na r1 (resp. fildes [1]), na-etinye ya na 4096 bytes nke data, mgbe nke ahụ gasịrị, a kwụsịrị usoro ide ihe. Mgbe ị na-agụ site na pipeline, aka ahụ laghachiri na r0 (resp. fildes[0]) na-ewe data ahụ.
A na-eche na ozugbo a kọwapụtara pipeline, usoro nkwurịta okwu abụọ (ma ọ bụ karịa) (nke a na-akpọ oku na-esote). ndụdụ) ga-ebufe data site na pipeline site na iji oku agụ и dee.
Shei ahụ nwere syntax maka ịkọwapụta usoro ahịrị ahịrị nke usoro ejikọrọ na pipeline.
Oku ka ịgụọ site na pipeline efu (enweghị data echekwara) nke nwere naanị otu njedebe (emechiri ihe nkọwa faịlụ ederede niile) weghachi "njedebe faịlụ". A na-eleghara oku iji dee n'ọnọdụ yiri nke ahụ.
Nke mbụ
mbipụta nke isii nke Unix (1975)
Ka anyị malite ịgụ koodu isi mmalite Unix
Ọtụtụ afọ akwụkwọ ọdum bụ naanị akwụkwọ dị na Unix kernel dị na mpụga Bell Labs. Ọ bụ ezie na akwụkwọ ikike mbipụta nke isii nyere ndị nkụzi ohere iji koodu isi mmalite ya, akwụkwọ ikike mbipụta nke asaa wepụrụ ohere a, n'ihi ya, a na-ekesa akwụkwọ ahụ n'ụdị mpempe akwụkwọ na-akwadoghị.
Taa ị nwere ike ịzụta mbipụta nke akwụkwọ ahụ, nke mkpuchi ya na-egosi ụmụ akwụkwọ na igwe oyiri. Na ekele Warren Toomey (onye malitere ọrụ TUHS) ị nwere ike ibudata
Ihe karịrị afọ 15 gara aga, pịnyere m otu koodu isi mmalite enyere ọdum, n'ihi na àgwà nke mbipụta m enweghị mmasị na ọnụọgụ ndị ọzọ amaghị. TUHS adịbeghị ma enweghị m ohere ịnweta isi mmalite ochie. Mana na 1988, ahụrụ m teepu ochie nke nwere ihe ndabere sitere na kọmputa PDP9. O siri ike ịmata ma ọ na-arụ ọrụ, ma e nwere osisi / usr / src / osisi na-adịghị emebi emebi nke a na-akpọ ọtụtụ faịlụ na afọ 11, nke ọbụna dị ka oge ochie. Ọ bụ mbipụta nke asaa ma ọ bụ PWB ewepụtara ya, dịka m kwenyere.
Eji m nchọta ahụ dị ka ntọala wee jiri aka dezie isi mmalite na mbipụta nke isii. Ụfọdụ n'ime koodu ahụ ka dị otu, mana ụfọdụ kwesịrị idezi ntakịrị, na-agbanwe akara ngosi += ọgbara ọhụrụ ka ọ bụrụ nke ochie =+. Ụfọdụ ihe ka ehichapụrụ, ma ụfọdụ ga-edegharị ya kpamkpam, mana ọ bụghị nke ukwuu.
Ma taa, anyị nwere ike ịgụ online na TUHS koodu isi iyi nke mbipụta nke isii si
Site n'ụzọ, na nlele mbụ, akụkụ bụ isi nke koodu C tupu oge Kernighan na Ritchie bụ ya. nkenke. Ọ bụghị mgbe niile ka m na-enwe ike itinye mpempe koodu na-enweghị nnukwu edezi ka ọ dabara ebe ngosi dị warara na saịtị m.
Na mbido
/*
* 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
Ogo nchekwa ahụ agbanwebeghị kemgbe mbipụta nke anọ. Mana ebe a, anyị na-ahụ, na-enweghị akwụkwọ ọhaneze ọ bụla, na pipeline otu oge ejiri faịlụ dịka nchekwa nchekwa!
Maka faịlụ LARG, ha na-edekọrịta
Nke a bụ ezigbo oku sistemụ 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;
}
Nkwupụta ahụ na-akọwa nke ọma ihe na-eme ebe a. Mana ịghọta koodu ahụ adịghị mfe, akụkụ ụfọdụ n'ihi ụzọ ahụ "R0
и R1
Sistemu oku parampat na nloghachi ụkpụrụ na-agafere.
Ka anyị nwaa ya
pipe()
ga-esi na ya R0
и R1
laghachi nọmba nkọwa faịlụ maka ịgụ na ide. falloc()
weghachi ihe ntụnye aka na nhazi faịlụ, mana ọ na-alaghachikwa site na u.u_ar0[R0]
na onye na-akọwa faịlụ. Ya bụ, koodu na-echekwa na r
onye na-akọwa faịlụ maka ịgụ ma nyefee onye na-akọwa faịlụ maka ide ozugbo site na u.u_ar0[R0]
mgbe oku nke abụọ gachara falloc()
.
Flag FPIPE
, nke anyị na-edozi mgbe ị na-emepụta pipeline, na-achịkwa omume nke ọrụ ahụ
/*
* 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);
}
/* … */
}
Mgbe ahụ ọrụ readp()
в pipe.c
na-agụ data sitere na pipeline. Ma ọ ka mma ịchọta mmejuputa iwu na-amalite writep()
. Ọzọ, koodu ahụ aghọwo ihe mgbagwoju anya n'ihi nkwekọrịta nke arụmụka na-agafe agafe, mana enwere ike ịhapụ nkọwa ụfọdụ.
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;
}
Anyị chọrọ ide bytes na ntinye pipeline u.u_count
. Mbụ anyị kwesịrị igbachi inode (lee n'okpuru plock
/prele
).
Mgbe ahụ, anyị na-elele counter inode. Ọ bụrụhaala na njedebe abụọ nke pipeline na-emeghe, counter kwesịrị ịdị nhata 2. Anyị na-ejide otu njikọ (site na rp->f_inode
), ya mere, ọ bụrụ na counter na-erughị 2, ọ ghaghị ịpụta na usoro ọgụgụ ahụ emechiwo njedebe nke pipeline. N'ikwu ya n'ụzọ ọzọ, anyị na-agbalị ịdegara pipeline mechiri emechi, nke a bụkwa njehie. Koodu njehie oge mbụ EPIPE
na mgbama SIGPIPE
pụtara na mbipụta nke isii nke Unix.
Mana ọ bụrụgodị na ebufe emeghere, ọ nwere ike ju. N'okwu a, anyị na-ahapụ mkpọchi ahụ wee hie ụra na-atụ anya na usoro ọzọ ga-agụ site na pipeline ma hapụ ohere zuru ezu na ya. Mgbe anyị tetara n'ụra, anyị na-alaghachi na mmalite, kwụgidere mkpọchi ọzọ wee malite usoro ndekọ ọhụrụ.
Ọ bụrụ na enwere ohere zuru oke na pipeline, mgbe ahụ, anyị na-eji ya ede data na ya i_size1
inode (ọ bụrụ na ọkpọkọ ahụ tọgbọ chakoo, ọ nwere ike ha nhata 0) na-egosi njedebe nke data nke o nwere. Ọ bụrụ na enwere ohere ndekọ zuru oke, anyị nwere ike mejupụta pipeline site na i_size1
ka PIPESIZ
. Mgbe ahụ, anyị na-ahapụ mkpọchi ahụ ma gbalịa ịkpọte usoro ọ bụla na-echere ịgụ site na pipeline. Anyị na-alaghachi na mmalite iji hụ ma anyị nwere ike ide ọtụtụ bytes dị ka anyị chọrọ. Ọ bụrụ na ọ daa, mgbe ahụ anyị na-amalite usoro ndekọ ndekọ ọhụrụ.
Na-emekarị oke i_mode
a na-eji inode chekwaa ikike r
, w
и x
. Ma n'ihe gbasara pipeline, anyị na-egosi na ụfọdụ usoro na-echere ka e dee ma ọ bụ gụọ site na iji bits IREAD
и IWRITE
n'otu n'otu. Usoro na-esetịpụ ọkọlọtọ na oku sleep()
, na a na-atụ anya na ụfọdụ usoro ọzọ n'ọdịnihu ga-akpata wakeup()
.
Ezi anwansi na-eme na sleep()
и wakeup()
. A na-emejuputa ha na
/*
* 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) /* … */
Usoro nke na-akpata sleep()
maka otu ọwa, enwere ike ịkpọte ya site na usoro ọzọ, nke ga-akpata wakeup()
maka otu ọwa. writep()
и readp()
hazie omume ha site na oku ejikọtara ọnụ. rụba nke ahụ ama pipe.c
mgbe niile na-enye ụzọ PPIPE
mgbe a na-akpọ ya sleep()
, yabụ ọ bụ ya sleep()
enwere ike ịkwụsị site na mgbama.
Ugbu a, anyị nwere ihe niile iji ghọta ọrụ ahụ 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);
}
Ị nwere ike ịhụ na ọ dịrị gị mfe ịgụ ọrụ a site na ala ruo n'elu. A na-ejikarị ngalaba "gụọ na nloghachi" mgbe enwere ụfọdụ data na pipeline. N'okwu a, anyị na-eji f_offset
ịgụ, wee melite uru nke nkwụghachi kwekọrọ.
Na agụ ndị na-esote, pipeline ga-atọgbọ chakoo ma ọ bụrụ na nkwụghachi nke ọgụgụ eruola i_size1
na inode. Anyị na-edozi ọnọdụ ahụ na 0 ma gbalịa ịkpọte usoro ọ bụla chọrọ ide na pipeline. Anyị maara na mgbe ebufe zuru oke, writep()
ga-ada n'ụra ip+1
. Ma ugbu a na pipeline tọgbọrọ chakoo, anyị nwere ike ịkpọte ya ka ọ maliteghachi usoro ihe odide ya.
Ọ bụrụ na ị nweghị ihe ịgụ, mgbe ahụ readp()
nwere ike ịtọ ọkọlọtọ IREAD
ma daa n'ụra ip+2
. Anyị maara ihe ga-akpọte ya writep()
, mgbe ọ na-ede ụfọdụ data na pipeline.
Azịza nye u
"Anyị nwere ike na-emeso ha dị ka ọrụ I/O nkịtị na-ewere faịlụ, ọnọdụ, ihe nchekwa na ebe nchekwa, ma gụọ ọnụọgụ bytes ka ịgụ ma ọ bụ dee.
/*
* 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;
/* … */
N'ihe gbasara igbochi "conservative", mgbe ahụ readp()
и writep()
gbochie inode ruo mgbe ha rụchara ọrụ ha ma ọ bụ nweta nsonaazụ (ya bụ, kpọọ wakeup
). plock()
и prele()
rụọ ọrụ nke ọma: iji usoro oku dị iche sleep
и wakeup
nye anyị ohere ịkpọte usoro ọ bụla chọrọ mkpọchi nke anyị wepụtara ugbu a:
/*
* 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);
}
}
Na mbụ, aghọtaghị m ihe kpatara ya readp()
adịghị akpata prele(ip)
tupu oku a wakeup(ip+1)
. Ihe mbụ bụ writep()
na-akpata na okirikiri ya, nke a plock(ip)
, nke na-eduga n'ịkwụ ụgwọ ma ọ bụrụ readp()
ewepụbeghị ngọngọ m, yabụ n'ụzọ ụfọdụ koodu ahụ ga-arụ ọrụ nke ọma. Ọ bụrụ na ị na-ele anya wakeup()
, Mgbe ahụ, ọ ga-edo anya na ọ bụ naanị akara usoro ihi ụra dị njikere ime, nke mere na n'ọdịnihu sched()
n'ezie ulo oru ya. Ya mere readp()
akpata wakeup()
, na-ewepu mkpọchi, setịpụ IREAD
na oku sleep(ip+2)
- ihe a niile tupu writep()
maliteghachi okirikiri.
Nke a mezuru nkọwa nke ndị na-ebugharị na mbipụta nke isii. Koodu dị mfe, nsonaazụ dị oke egwu.
Xv6, kernel dị mfe dịka Unix
Iji mepụta kernel
Koodu ahụ nwere mmejuputa doro anya na nke echebara echiche 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()
na-esetịpụ ọnọdụ nke ndị ọzọ nke mmejuputa iwu, nke gụnyere ọrụ piperead()
, pipewrite()
и pipeclose()
. Oku sistemu n'ezie sys_pipe
bụ ihe mkpuchi etinyere na
Linux 0.01
Enwere ike ịchọta koodu isi iyi Linux 0.01. Ọ ga-abụ ihe mmụta iji mụọ mmejuputa pipelines na ya fs
/pipe.c
. Nke a na-eji inode na-anọchi anya pipeline, ma pipeline n'onwe ya ka edere na nke oge a C. Ọ bụrụ na ị na-arụ ọrụ gị site na koodu mbipụta nke 6, ị gaghị enwe nsogbu ebe a. Nke a bụ ihe ọrụ ahụ dị ka 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;
}
Ọbụlagodi na-elele nkọwa nhazi, ị nwere ike ịchọpụta ka esi eji ọnụ ọgụgụ inode iji lelee ma ọrụ ide ọ rụpụtara. SIGPIPE
. Na mgbakwunye na ịrụ ọrụ byte-byte, ọrụ a dị mfe iji tụnyere echiche ndị akọwapụtara n'elu. Ọbụna mgbagha sleep_on
/wake_up
adịghị anya otú ọbịa.
Mkpụrụ ndụ Linux ọgbara ọhụrụ, FreeBSD, NetBSD, OpenBSD
M ngwa ngwa gafere ụfọdụ kernel ọgbara ọhụrụ. Ọ dịghị nke ọ bụla n'ime ha nwere mmejuputa diski ọzọ (ọ bụghị ihe ijuanya). Linux nwere mmejuputa ya. Ọ bụ ezie na mkpụrụ ndụ BSD atọ nke ọgbara ọhụrụ nwere mmejuputa iwu dabere na koodu nke John Dyson dere, n'ime afọ ha adịla iche na ibe ha.
Ịgụ fs
/pipe.c
(na Linux) ma ọ bụ sys
/kern
/sys_pipe.c
(na *BSD), ọ na-achọ ezigbo nraranye. Koodu nke taa bụ maka arụmọrụ yana nkwado maka njirimara dịka vector na I/O asynchronous. Na nkọwa nke oke ebe nchekwa, mkpọchi na nhazi kernel niile dịgasị iche iche. Nke a abụghị ihe kọleji chọrọ maka nkuzi sistemụ arụmọrụ mmalite.
Agbanyeghị, enwere m mmasị igwupụta ụfọdụ ụkpụrụ ochie (dị ka imepụta SIGPIPE
ma laghachi EPIPE
mgbe ị na-ede na pipeline mechiri emechi) n'ime kernel ndị a niile dị iche iche nke oge a. Agaghị m ahụ kọmputa PDP-11 na ndụ n'ezie, mana a ka nwere ọtụtụ ihe m ga-amụta na koodu e dere ọtụtụ afọ tupu a mụọ m.
Edemede nke Divi Kapoor dere na 2011:
isi: www.habr.com