第一次自測(cè)
結(jié)合文件I/O內(nèi)核數(shù)據(jù)結(jié)構(gòu),說(shuō)明系統(tǒng)調(diào)用函數(shù)open的執(zhí)行過(guò)程。
答:當(dāng)程序中執(zhí)行open函數(shù)打開(kāi)時(shí)文件時(shí),系統(tǒng)首先檢查該文件的v_node是否存在,若不存在,則先為其創(chuàng)建其v_node,將文件的屬性從外存讀入v-node;接著,創(chuàng)建其文件表(file table)表項(xiàng),設(shè)置讀寫(xiě)方式、讀寫(xiě)位置、v-node指針,訪問(wèn)計(jì)數(shù)器置為1;然后,在進(jìn)程的描述符表中找到索引號(hào)最小的空閑表項(xiàng),在其中填入文件表表項(xiàng)的指針,返回描述符表項(xiàng)的索引號(hào)
第二次自測(cè)
若盤(pán)塊大小為 2KB ,塊地址用4字節(jié)表示,文件系統(tǒng)采用索引組織,索引項(xiàng)0至索引項(xiàng)9為直接索引,索引項(xiàng)10為一級(jí)間接索引,索引項(xiàng)11為二級(jí)間接索引,索引項(xiàng)12為三級(jí)間接索引,若文件索引節(jié)點(diǎn)已在內(nèi)存,
(1)該系統(tǒng)支持的最大文件大小是多少?
(2)請(qǐng)計(jì)算從以下文件位置620 0000處讀出10K字節(jié)數(shù)據(jù),需要讀寫(xiě)多少個(gè)磁盤(pán)塊?

解:
(1)最大文件大小為:
(10+512+5122+5123)×2KB
=20KB+1MB+512MB+256GB
(2)從位置620 0000處讀出10K字節(jié)數(shù)據(jù),其首字節(jié)位置為620 0000,末字節(jié)位置為6210239,對(duì)應(yīng)的相對(duì)塊號(hào)分別為:
620 0000/2048=3027.34
621 0239/2048=3032.34
由于直接索引、一級(jí)間接索引、二級(jí)間接索引下登記的磁盤(pán)塊數(shù)分別為10、512、5122而522<3027、3032<5122 這些數(shù)據(jù)塊的磁盤(pán)塊號(hào)都登記在二級(jí)間接指針之下;
同時(shí)(3027-522)/512=4.89,(3032-512)/ 512=4.90,這些數(shù)據(jù)塊的磁盤(pán)塊號(hào)都登記在4號(hào)索引塊中。因此需要讀取的磁盤(pán)塊數(shù)為2+3032-3027+1=8個(gè)。
讀出10KB數(shù)據(jù)需要讀寫(xiě)8個(gè)磁盤(pán)塊。
- 要編寫(xiě)一個(gè)多進(jìn)程應(yīng)用程序,各進(jìn)程之間關(guān)系如圖所示,要求各個(gè)進(jìn)程輸出其方框中的進(jìn)程名。

答:
int main() {
int pid;
printf(“p1\n”);
pid=fork();
if(pid==0) {
printf(“p11\n”)
exit(0);
}
pid=fork();
if(pid==0) {
printf(“p12\n”)
exit(0);
}
pid=fork();
if(pid==0) {
printf(“p13\n”)
pid=fork();
if(pid==0) printf(“p131\n”)
}
給出導(dǎo)致進(jìn)程狀態(tài)轉(zhuǎn)換的事件:
(1)運(yùn)行就緒狀態(tài)轉(zhuǎn)換,1種;
(2)創(chuàng)建就緒,1種;
(3)運(yùn)行阻塞,2種;
(4)運(yùn)行終止,2種。
答:
(1)時(shí)間片用完
(2)fork
(3)scanf、read
(4)exit、被0除
第三次自測(cè)
閱讀下面程序代碼,請(qǐng)分析從理論上有哪幾種可能的輸出結(jié)果。
int x=y=1;
void * thread1(void *arg) { x=y*5;}
void * thread2(void *arg) { y=x*10;}
int main()
{ pthread_t t1,t2,t3;
pthread_create(&t1,NULL,thread1,NULL);
pthread_create(&t2,NULL,thread2,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
printf("x=%d y=%d\n",x,y);
}
答:
(1)x=5 y=10 //同時(shí)
(2)x=5 y=50
(3)x=50 y=10
生產(chǎn)者/消費(fèi)者程序代碼
#define N 10
int buf[N], outpos=0, inpos=0;
void produce() {
while (1){
item=produce();
sbuf_insert(item,buf); //insert
}
}
void consumer() {
while (1){
item=sbuf_remove(buf); //remove
consume(item);
}
}
void sbuf_insert(item,buf) {
buf[inpos]=item;
inpos=(inpos+1) mod N;
}
intsbuf_remove(buf) {
item=buf[outpos];
outpos=(outpos+1) mod N;
return item;
}
int main() {
int k, m, i,; pthread_t tid;
scanf("%d%d”, &k,&m);
for(i=0; i<m; i++)
pthread_create(&tid, NULL, produce, NULL);
for(i=0; i<p; i++)
pthread_create(&tid, NULL, consumer, NULL);
}
消費(fèi)者與生產(chǎn)者競(jìng)爭(zhēng)緩沖區(qū)avail = 0, ready = 0
消費(fèi)者之間競(jìng)爭(zhēng)主導(dǎo)權(quán)mutex = 1
#define N 20
int buf[N]; int outpos=0; int inpos=0;
semaphore avail=N, ready=0;
semaphore mutex1=mutex2 =1;
void Thread_Pi() //生產(chǎn)者線(xiàn)程,有k個(gè)
{
while (1) {
item=produce(); //產(chǎn)生數(shù)據(jù)
wait(avail); wait(mutex1);
sbuf_insert(item,buf); //向緩沖區(qū)投放數(shù)據(jù)
signal(mutex1); signal(ready);
}
}
void Thread_Ci() //消費(fèi)者線(xiàn)程,有m個(gè)
{
while (1) {
wait(ready); wait(mutex2);
item=sbuf_remove(buf); //從緩沖區(qū)去數(shù)據(jù)
signal(mutex2); signal(avail);
consume(item); //消費(fèi)或處理數(shù)據(jù)
}
}
void sbuf_insert(item, buf) //數(shù)據(jù)寫(xiě)入函數(shù)
{ buf[inpos]=item;
inpos=(inpos+1)mod N;
}
int sbuf_remove(buf) //數(shù)據(jù)讀出函數(shù)
{ item=buf[outpos];
outpos=(outpos+1) mod N;
return item;
}
- 某超級(jí)市場(chǎng),可容納100個(gè)人同時(shí)購(gòu)物,入口處備有籃子,每個(gè)購(gòu)物者可持一個(gè)籃子入內(nèi)購(gòu)物。出口處結(jié)賬,并歸還籃子,出、入口僅容納一人通過(guò)。請(qǐng)用P、V操作完成購(gòu)物同步算法。
解:
semaphore mutex1=mutex2=1, baskets=N;
semaphore sem=100;
互斥量mutex1是入門(mén), mutex2是出門(mén)
信號(hào)量Baskets:籃子的個(gè)數(shù), Sem:可容納的人數(shù)
Customer() {
Wait(sem);//
Wait(baskets); //取購(gòu)物籃
Wait(mutex1); //得到入門(mén)
Signal(mutex1);//入門(mén)
Wait(mutex2);//得到出門(mén)
Signal(mutex2);//出門(mén)
Signal(baskets);//返還籃子
Signal(sem);//
}
7. 試用信號(hào)量實(shí)現(xiàn)這6個(gè)代碼段的同步

Semaphore s12=s13=s24=s25=s46=s56=s36=0;

s1只生產(chǎn)信號(hào)量不需要得到信號(hào)量
其他的線(xiàn)程都需要得到上一步的信號(hào)量
- 今有三個(gè)并發(fā)進(jìn)程R,M,P,它們共享了一個(gè)可循環(huán)使用的緩沖區(qū)B,緩沖區(qū)B共有N個(gè)單元。
進(jìn)程R負(fù)責(zé)從輸入設(shè)備讀信息,每讀一個(gè)字符后,把它存放在緩沖區(qū)B的一個(gè)單元中;
進(jìn)程M負(fù)責(zé)處理讀入的字符,若發(fā)現(xiàn)讀入的字符中有空格符,則把它改成“,”;
進(jìn)程P負(fù)責(zé)把處理后的字符取出并打印輸出。當(dāng)緩沖區(qū)單元中的字符被進(jìn)程P取出后,則又可用來(lái)存放下一次讀入的字符。
請(qǐng)用PV操作為同步機(jī)制寫(xiě)出它們能正確并發(fā)執(zhí)行的程序。
解:
Semaphore avail=N, ready1=0,ready2=0;//
char B[N];//緩沖區(qū)
int pos1=pos2=pos3=0;//下標(biāo)
R() {
while(1) {
<<從設(shè)備讀取一個(gè)字符ch>>
wait(avail);//獲得一個(gè)空閑空間-1
B[pos1]=ch;
pos1=(pos1+1) mod N;
signal(ready1);//增加一個(gè)字符,生產(chǎn)+1
}
}
M() {
while(1) {
wait(ready1);//得到一個(gè)產(chǎn)品 -1
ch=B[pos2];
if(ch==’ ‘) ch=’,’;
B[pos2]=ch;
pos2=(pos2+1) mod N;
signal(ready2);//加工一個(gè)新產(chǎn)品 + 1
}
}
P() {
while(1) {
wait(ready2);//得到一個(gè)新產(chǎn)品 - 1
B[pos3]=ch;
pos3=(pos3+1) mod N;
signal(avail);//釋放一個(gè)空閑空間+1
}
}
-
有一座橋如圖所示,車(chē)流如圖中箭頭所示。橋上不允許兩車(chē)交會(huì),但允許同方向多輛車(chē)依次通行(即橋上可以有多個(gè)同方向的車(chē))。用信號(hào)量和P、V操作實(shí)現(xiàn)交通管理,寫(xiě)出描述代碼,以防止橋上堵塞。
重點(diǎn)題型
分析:
兩個(gè)線(xiàn)程函數(shù)EasttoWest, WesttoEaset
每個(gè)方向上的車(chē)輛都要對(duì)當(dāng)前通行的車(chē)輛做統(tǒng)計(jì),以確保自己是否要和敵方爭(zhēng)奪通道的使用權(quán),為防止多個(gè)同方向的線(xiàn)程同時(shí)對(duì)count進(jìn)行操作,需要互斥量mutex1, mutex2.另外還需要一個(gè)爭(zhēng)奪通道權(quán)的互斥量wmutex
semaphore mutex1=mutex2=wmutex=1;
int count1=count2=0;
EasttoWest() {
wait(mutex1);
count1++;
if(count1==1) wait(wmutex);
signal(mutex1);
汽車(chē)走過(guò)單行道
wait(mutex1);
count1--;
if(count1==0) signal(wmutex);
signal(mutex1);
}
WesttoEaset() {
wait(mutex2);
count2++;
if(count2==1) wait(wmutex);
signal(mutex2);
汽車(chē)走過(guò)單行道
wait(mutex2);
count2--;
if(count2==0) signal(wmutex);
signal(mutex2);
}
