版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2023-2023學(xué)年第2學(xué)期操作系統(tǒng)課程設(shè)計(jì)
規(guī)定:
1.每位同學(xué)按學(xué)號(hào)尾數(shù)作相應(yīng)的課題,如1號(hào)同學(xué)做課題一,2號(hào)同學(xué)作課題二。
2.允許同學(xué)之間換題。
3.允許用不同的方法作課題,即可以在Windows、Linux下采用各種編程
語(yǔ)言和開(kāi)發(fā)工具實(shí)現(xiàn)課題所規(guī)定的功能。(所附資料僅供參考)
課程設(shè)計(jì)報(bào)告格式
一、課程設(shè)計(jì)目的
二、課題內(nèi)容
三、設(shè)計(jì)思緒
四、源代碼
五、運(yùn)營(yíng)與測(cè)試
六、心得體會(huì)
課題一:編寫(xiě)一個(gè)小型命令解決器sma1Ishe1I
一、目的
設(shè)計(jì)并實(shí)現(xiàn)一個(gè)簡(jiǎn)樸的命令解決程序,名字為smallshe11。規(guī)定具有以下基本功能:
1.支持交互式的用戶(hù)界面
2.支持內(nèi)置命令:cd,exit,設(shè)立搜索途徑path等。
3.支持可執(zhí)行文獻(xiàn)的運(yùn)營(yíng)
4.支持輸入輸出重定向功能
5.支持管道功能
二、準(zhǔn)備知識(shí)
1.交互式用戶(hù)界面
在sma11shell中,顯示如下格式的交互界面:
[semame@servername:pathname]$
需要涉及以下函數(shù):
#include<uniste.h>
char*get1ogin(void);
/*getlogin函數(shù)返回與當(dāng)前用戶(hù)關(guān)聯(lián)的用戶(hù)名*/
intgethostname(char*name,size_tnamelen);
/*gethostname函數(shù)把機(jī)器的網(wǎng)絡(luò)名寫(xiě)到字符串name中,name的長(zhǎng)度為namelen,因此
該字符串的長(zhǎng)度不得超過(guò)name1en個(gè)字符,函數(shù)成功返回0,否則返回-1。*/
#include<unistd>
char*getcwd(char*name,size_tsize);
/getcwd函數(shù)返回一個(gè)指向當(dāng)前工作目錄的指針,并將當(dāng)前工作目錄存于name中,假如
該目錄名長(zhǎng)度超過(guò)size給出的長(zhǎng)度,返回NULL。若size為0,返回一1。*/
例如,下面這段程序模仿了pwd命令:
#inc1ude<stdio.h>
#inc1ude<unistd.h>
#defineVERYBIG200
voidmy_pwd(void);
main()
{
my_pwd();
}
voidmy_pwd(void);
{
chardirname[VERYBIG];
if(getcwd(dirname,VERYBIG)==NULL)
printf("geicwderror");
else
printf("%s”,dirname);
)
2.支持內(nèi)置命令:cd,exit,設(shè)立搜索途徑path等。
假如用戶(hù)輸入內(nèi)置命令,smal1she11根據(jù)命令名及參數(shù)進(jìn)行相應(yīng)解決。下面以cd,
exit,path命令為例,分別說(shuō)明其實(shí)現(xiàn)所涉及的函數(shù)。。
(1)cd命令
該命令用于切換當(dāng)前目錄,可以通過(guò)chdir()函數(shù)實(shí)現(xiàn)。chdir()使當(dāng)前目錄變?yōu)閜ath所
指向的目錄,該函數(shù)的用法如下:
#inc1ude<unistd.h>
intchdir(constchar*path);
chdir在失敗的情況下返回-1。需要注意的是,chdir只影響調(diào)用進(jìn)程,并不會(huì)影響啟動(dòng)這
個(gè)進(jìn)程的she11進(jìn)程。
例如,使用chdir("/usr/bin");可切換到/usr/bin目錄。
(2)exit命令
。該命令用于退出smallshell,需要調(diào)用exit函數(shù)實(shí)現(xiàn),exit函數(shù)用法如下:
#include<stdlib.h>
?voidexit(intstatus);
(3)path命令
。該命令用于設(shè)立搜索途徑。可以設(shè)立一個(gè)全局變量gpath,實(shí)現(xiàn)對(duì)搜索途徑的更新。
3.支持可執(zhí)行文獻(xiàn)的運(yùn)營(yíng)
假如用戶(hù)輸入的不是內(nèi)置命令,而是一個(gè)可執(zhí)行文獻(xiàn)名,則需要在設(shè)立的途徑中搜索該命令,
并在此環(huán)境中執(zhí)行。可以通過(guò)access()函數(shù)先對(duì)該命令進(jìn)行測(cè)試:
#inc1ude<unistd.h>
intaccess(constchar*pathname,intmode);
該函數(shù)根據(jù)用戶(hù)id測(cè)定進(jìn)程是否具有訪問(wèn)某個(gè)特定文獻(xiàn)的權(quán)限。參數(shù)pathname表
達(dá)的是文獻(xiàn)的名字,參數(shù)mode有三種也許的取值,它們的定義在<unistd.h>中可以找到:
R_OK調(diào)用進(jìn)程是否具有讀訪問(wèn)權(quán)限
W_OK調(diào)用進(jìn)程是否具有寫(xiě)訪問(wèn)權(quán)限
X_OK調(diào)用進(jìn)程是否具有執(zhí)行權(quán)限
access函數(shù)返回0,表達(dá)用戶(hù)對(duì)文獻(xiàn)具有訪問(wèn)權(quán)限,返回-1表達(dá)不具有此種訪問(wèn)
權(quán)限。
假如命令可執(zhí)行,下一步是創(chuàng)建smallsheII的子進(jìn)程,之后讓子進(jìn)程執(zhí)行這個(gè)可執(zhí)行文獻(xiàn)。
因此需要用到fork和exec類(lèi)函數(shù)。f。rk函數(shù)的使用請(qǐng)參考課程實(shí)驗(yàn)指導(dǎo)書(shū),exec類(lèi)函
數(shù)有6個(gè),這里可以用其中的execve()函數(shù),用法如下:
#include<unistd.h>
intexecve(constchar*pathname,char*constargv[],char*constenvp
[];
pathname參數(shù)是子進(jìn)程要執(zhí)行的文獻(xiàn)的途徑名,argv是一個(gè)參數(shù)字符串列表,envp是一
個(gè)
環(huán)境變量字符串和值的列表。execve成功不會(huì)返回,失敗返回一1.
例:
cmd=^^helloworld";//helloworld是一一個(gè)可執(zhí)行文獻(xiàn)
char*envp[]={"PATH=/home/stul”,0};
exeeve(emd,NULL,envp);〃執(zhí)行he1lowor1d
4.支持輸入輸出重定向功能
每個(gè)進(jìn)程的描述符中包含一個(gè)file_struct結(jié)構(gòu),記錄用戶(hù)的文獻(xiàn)打開(kāi)情況,這個(gè)結(jié)構(gòu)稱(chēng)為用
戶(hù)打開(kāi)文獻(xiàn)表。并且用戶(hù)打開(kāi)文獻(xiàn)表的信息在fork()和exec()調(diào)用后將仍然保持和繼承。
進(jìn)程的打開(kāi)文獻(xiàn)表記錄進(jìn)程已經(jīng)打開(kāi)的文獻(xiàn)描述符,即指向文獻(xiàn)對(duì)象的指針。通常系統(tǒng)為正
在執(zhí)行的進(jìn)程自動(dòng)打開(kāi)三個(gè)文獻(xiàn):標(biāo)準(zhǔn)輸入(鍵盤(pán)),標(biāo)準(zhǔn)輸出(顯示器),標(biāo)準(zhǔn)錯(cuò)誤。通常相
應(yīng)文獻(xiàn)描述符0,1,2。因此,輸入輸出重定向?qū)嶋H就是將標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的文獻(xiàn)描
述符指向用戶(hù)指定的文獻(xiàn)??梢允褂孟铝泻瘮?shù)實(shí)現(xiàn):
#inc1ude<unistd.h>
fid=open(constchar*pathname,intf1ags);
intdup2(intoldfd,intnewfd);
open函數(shù)打開(kāi)一個(gè)文獻(xiàn),返回該文獻(xiàn)的描述符。參數(shù)pathname是文獻(xiàn)的途徑名,flag指
定文獻(xiàn)存取模式,取值為:O_RD0NLY,O_WRONLY,O_RDWR,O_CREATE等。
dup2函數(shù)將老的文獻(xiàn)描述符。1dfd復(fù)制到新的文獻(xiàn)描述符newfd,即創(chuàng)建一個(gè)。1dfd的
拷貝。
例如:
fid=open(fi1ename,O_WRONLY|O_CREAT);
//以寫(xiě)的方式創(chuàng)建并打開(kāi)文獻(xiàn)fi1ename
dup2(fid,l);〃將文獻(xiàn)描述符復(fù)制到標(biāo)準(zhǔn)輸出,即輸出時(shí)便輸出到新建文獻(xiàn)
中,
〃從而實(shí)現(xiàn)了輸出重定向。
5.支持管道功能
she11中的管道功能是將一個(gè)命令的輸出作為另一個(gè)命令的輸入。可以用pipe函數(shù)創(chuàng)建無(wú)
名管道。返回的Pipe文獻(xiàn)描述符只能被同一家族的父子進(jìn)程使用,因此可以用fork函數(shù)
和exec函數(shù)創(chuàng)建兩個(gè)不同的進(jìn)程并使其具有父子關(guān)系,之后使一個(gè)進(jìn)程的輸出重定向到管
道,另一個(gè)進(jìn)程的輸入重定向到管道,從而實(shí)現(xiàn)管道功能。程序框架如下:
intfd[2];
pipe(fd);
if(fork>0){//父進(jìn)程
c1ose(fd[0]);//關(guān)閉用于讀文獻(xiàn)的描述符
dup2(fd[l],l);〃父進(jìn)程實(shí)現(xiàn)輸出重定向
)
else{//子進(jìn)程
close(fdEl]);//關(guān)閉用于寫(xiě)的文獻(xiàn)描述符
dup2(fd[0],0);〃子進(jìn)程實(shí)現(xiàn)輸入重定向
三、smal1shel1總體結(jié)構(gòu)
?課題二使用SystemV的IPC機(jī)制實(shí)現(xiàn)“生產(chǎn)者-消費(fèi)者”問(wèn)題
一、目的
學(xué)習(xí)SystemV的進(jìn)程間通信機(jī)制,使用信號(hào)量和共享內(nèi)存實(shí)現(xiàn)經(jīng)典進(jìn)程同步問(wèn)題“生產(chǎn)者一
消費(fèi)者”問(wèn)題。具體規(guī)定:
1.創(chuàng)建信號(hào)量集,實(shí)現(xiàn)同步互斥信號(hào)量。
2.創(chuàng)建共享內(nèi)存,模擬存放產(chǎn)品的公共緩沖池。
3.創(chuàng)建并發(fā)進(jìn)程,實(shí)現(xiàn)進(jìn)程對(duì)共享緩沖池的并發(fā)操作。
二、準(zhǔn)備知識(shí)
1.信號(hào)量集
(1)創(chuàng)建信號(hào)量集
#inc1ude<sys/sem.h>
intsemget(key_tkey,intnsems,intpermflags);
該調(diào)用與文獻(xiàn)的open或creat相似,參數(shù)key是一個(gè)標(biāo)記信號(hào)量集的數(shù),參數(shù)nsems是信
號(hào)量集中包含的信號(hào)量的個(gè)數(shù),元素索引從。到nsems-1,permflags是semget函數(shù)將
實(shí)現(xiàn)的操作,有兩個(gè)值供選擇,在頭文獻(xiàn)<sys/ipc.h>有定義,這兩個(gè)值可以單獨(dú)使用,也可
用"或''位運(yùn)算符連起來(lái)使用:
IPC_CREAT:創(chuàng)建一個(gè)key所代表的新信號(hào)量集,類(lèi)似于creat。
IPC_EXCL:同IPC_CREAT都設(shè)立時(shí),若key相應(yīng)信號(hào)量集存在,則返回-1,并將錯(cuò)誤
指示變量errno置EEXIST?
例如:semid=semget((key_t)OO10,1,0600IIPC_CREAT|IPC_EXCL);
注意:這里0600表達(dá)對(duì)該信號(hào)量集的存取權(quán)限,設(shè)立的方式同文獻(xiàn)存取權(quán)限的設(shè)立一致。
0600表達(dá)對(duì)信號(hào)量集的創(chuàng)建者具有讀寫(xiě)權(quán)限,對(duì)同組用戶(hù)和其他用戶(hù)無(wú)任何權(quán)限。
(2)信號(hào)量控制
#include<sys/sem.h>
intsemctl(intsemid,intsem_num,intcommand,unionsemunct1_arg);
該函數(shù)可以對(duì)semid表達(dá)的信號(hào)量集中的第sem_num號(hào)信號(hào)量執(zhí)行c。mmand指示的
操作。sem_num是信號(hào)量的索引號(hào),注意,索引號(hào)從0開(kāi)始。command給出要完畢何種功
能,功能可分為種:標(biāo)準(zhǔn)IPC功能、只對(duì)單個(gè)信號(hào)量起作用的功能、影響整個(gè)信號(hào)量集的功
能。
標(biāo)準(zhǔn)IPC函數(shù)
IPC_STAT:把狀態(tài)信息放入ct1_arg.buf
IPC_SET:用stJarg.buf中的值設(shè)立信號(hào)量的所有權(quán)/許可權(quán)
IPC_RMID:從系統(tǒng)中刪除信號(hào)量集(此時(shí)sem_num參數(shù)忽略)
單信號(hào)量操作
GETVAL:返回信號(hào)量的值
SETVAL:設(shè)立信號(hào)量的值,寫(xiě)入ctl_arg.val
GETPID:返回最后一個(gè)對(duì)sem_num號(hào)信號(hào)量執(zhí)行semop操作的進(jìn)程id
GETNCNT:返回等待sem_num號(hào)信號(hào)量值增長(zhǎng)的進(jìn)程數(shù),即在該信號(hào)量上等待的進(jìn)程
數(shù)
GETZCNT:返回等待sem_num號(hào)信號(hào)量值變?yōu)?的進(jìn)程數(shù)。
全信號(hào)量操作
GETALL:返回所有信號(hào)量的值,結(jié)果保存在ctl_arg.array,忽略參數(shù)sem_num
SETALL:通過(guò)ct1_arg.array更新所有信號(hào)量的值。
參數(shù)sem_num與上述第二類(lèi)功能選項(xiàng)一起使用,以針對(duì)某一個(gè)信號(hào)量。參數(shù)ctl_arg是調(diào)
用該函數(shù)的進(jìn)程必須事先定義的一個(gè)聯(lián)合體,定義如下;
unionsemun{
intval;
structsemid_ds*buf;
unsignedshort*array
);
unionsemunctl_arg;
聯(lián)合體中的三個(gè)成員分別相應(yīng)semct1的三個(gè)功能,val是針對(duì)信號(hào)量值的,例如賦初值。
結(jié)構(gòu)體semid_ds是IPC_STAT和IPC_SET的緩沖,array針對(duì)全信號(hào)量操作。
(3)信號(hào)量操作
#include<sys/sem.h>
intsemop(intsemid,structsembuf*op_array,size_tnum_ops);
該函數(shù)可以實(shí)現(xiàn)信號(hào)量的p、v操作。參數(shù)semid是信號(hào)量集的標(biāo)記符,op_array指向s
embuf結(jié)構(gòu)體類(lèi)型的數(shù)組,參數(shù)num_ops是操作的個(gè)數(shù)。下面給出sembuf的結(jié)構(gòu):
structsembuf{
unsignedshortsem_num;//存放信號(hào)量在信號(hào)量集合中的索引
oShortsem_op;〃1,-1分別可表達(dá)加一和減一操作,相稱(chēng)與V、P操作
"shortsem_f1g;//標(biāo)志,設(shè)立SEM_UNDO表達(dá)進(jìn)程退出時(shí)自動(dòng)還原
)
例如,下面這段程序可以實(shí)現(xiàn)針對(duì)一個(gè)信號(hào)量的P操作:
intP(intsemid)
6//semid是信號(hào)量集的標(biāo)記符
{structsembufp_buf;
oP_buf.sem_num=0;0
p__buf.sem_op=-1;
op_buf.sem_f1g=SEM_UNDO;
if(semop(semid,&p_buf,1)==-1)〃第三個(gè)參數(shù)是p—buf指向的sem
buf數(shù)組的大小
。{perror("p(semid)fai1edn);
。exit(1);
°)
retum(0);
)
2.共享存儲(chǔ)
共享存儲(chǔ)操作適得兩個(gè)或兩個(gè)以上的進(jìn)程可以共用一段物理內(nèi)存(一般情況下,兩個(gè)進(jìn)程的
數(shù)據(jù)區(qū)是完全獨(dú)立的,父進(jìn)程用fork創(chuàng)建子進(jìn)程后,子進(jìn)程會(huì)復(fù)制父進(jìn)程數(shù)據(jù)到自己的
數(shù)據(jù)區(qū))。
(1)創(chuàng)建共享內(nèi)存
#inc1ude<sys/shm.h>
intshmget(key_tkey,size_tsize,intpermflags);
參數(shù)key是共享內(nèi)存的標(biāo)記,size是共享內(nèi)存段的最小字節(jié)數(shù),permflags是訪問(wèn)權(quán)限,
值的設(shè)立同semget同樣。
(2)共享內(nèi)存的控制
#include<sys/shm.h>
intshmct1(intshmid,intcommand,structshmid_ds*shm_stat);
該函數(shù)semet1相似,command可設(shè)為IPC_STAT,IPC_SET,IPC_RMIDO參數(shù)shm_s
tat指向存放屬性的結(jié)構(gòu)體,具體內(nèi)容請(qǐng)參考手冊(cè)。
(3)共享內(nèi)存的附接和斷開(kāi)
#include<sys/shm.h>
void*shmat(intshmid,constvoid*addr,intshmf1ags);
intshmdt(constvoid*addr);
由于兩個(gè)函數(shù)需指出進(jìn)程地址空間中的地址,因此比較復(fù)雜。簡(jiǎn)化的方法是將shmat中的
地址設(shè)為NULLo
三、程序框架
//semaphoreheaderfi1e
#include<sys/types.h>
#include<sys/ipc.h>
#include<sysZsem.h>
#inc1ude<errno.h>
#inc1ude<stdlib.h>
#inc1ude<stdio.h>
#include<unistd.h>
typedefunion_semun{
//定義聯(lián)合體
}semun;
structdatabuf{〃定義“生產(chǎn)者-消費(fèi)者”問(wèn)題中存放數(shù)據(jù)的buffer
);
staticintshmid,semid;
voidinitshm(structdatabuf**p)〃創(chuàng)建共享存儲(chǔ)區(qū),并附接到調(diào)用進(jìn)程
(
)
intinitsem()
//創(chuàng)建信號(hào)量集,并初始化
)
voidremobj(void)
//刪除IPC對(duì)象
if(shmctl(shmid,IPC_RMID,NULL)==—1)printf(nshmctlerror1');
if(semctl(semid,IPC_RMID,0)==—1)printf("\nsemctlremobjerror\
intP()
〃定義p操作
。}
intV()〃定義v操作
{
}
voidproducer()//生產(chǎn)者
voidconsumer()
//消費(fèi)者
main()//主程序
(
key_tsemkey,shmkey;
structdatabuf*buf;//產(chǎn)品緩沖池
initshm(&buf);//創(chuàng)建共享存儲(chǔ)區(qū),并附接到buf指針指示的位置
semid=initsem(semkey);//創(chuàng)建信號(hào)量集
..//創(chuàng)建若干并發(fā)進(jìn)程,實(shí)現(xiàn)producer與consume
r的并發(fā)執(zhí)行
remobjO;。?!▌h除IPC對(duì)象…
)
?課題三使用SystemV的IPC機(jī)制實(shí)現(xiàn)“讀者-寫(xiě)者”問(wèn)題
一、目的
學(xué)習(xí)SystemV的進(jìn)程間通信機(jī)制,使用信號(hào)量和共享內(nèi)存實(shí)現(xiàn)經(jīng)典進(jìn)程同步問(wèn)題“讀者-
寫(xiě)者”問(wèn)題。具體規(guī)定:
1.創(chuàng)建信號(hào)量集,實(shí)現(xiàn)互斥信號(hào)量。
2.創(chuàng)建共享內(nèi)存,將“讀者一寫(xiě)者”共享的文獻(xiàn)保存其中,并保存讀者共享的計(jì)數(shù)值。
3.創(chuàng)建并發(fā)進(jìn)程,實(shí)現(xiàn)“讀者-寫(xiě)者”的并發(fā)操作。
二、準(zhǔn)備知識(shí)
見(jiàn)課題二
三、程序框架
//semaphoreheaderfile
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.h>
#include<std1ib.h>
#include<stdio.h>
#include<unistd.h>
typedefunion_semun{
//定義聯(lián)合體
}semun;
staticintshmid,semid;
voidinitshm(structdatabuf**p)//創(chuàng)建共享存儲(chǔ)區(qū),并附接到調(diào)用進(jìn)程
intinitsem()
〃創(chuàng)建信號(hào)量集,并初始化
voidremobj(void)
//刪除IPC對(duì)象
{
if(shmet1(shmid,IPC_RMID,NULL)==-1)printf("shmct1error");
if(semetl(semid,IPC_RMID,0)==-1)printf("\nsemctlremobjerror\n");
}
intP()
〃定義p操作
intV()//定義v操作
voidreader()//讀者
)
voidwriter()//寫(xiě)者
(
)
main()〃主程序
{
key_tsemkey,shmkey;
int*readercount//讀者計(jì)數(shù)值
initshm(&readercount);〃創(chuàng)建共享存儲(chǔ)區(qū),并附接到readercount
指針指示的位置
semid=initsem(semkey);〃創(chuàng)建信號(hào)量集
.......〃創(chuàng)建若干并發(fā)進(jìn)程,實(shí)現(xiàn)producer與consum
er的并發(fā)執(zhí)行
remobj();〃刪除IPC對(duì)象。
課題四運(yùn)用信號(hào)量和多線程機(jī)制實(shí)現(xiàn)“哲學(xué)家進(jìn)餐”問(wèn)題
一、目的
學(xué)習(xí)多線程編程,使用線程的同步機(jī)制實(shí)現(xiàn)“哲學(xué)家進(jìn)餐”問(wèn)題。具體規(guī)定:
1.創(chuàng)建POSIX線程,實(shí)現(xiàn)多線程的并發(fā)執(zhí)行,驗(yàn)證多線程共享進(jìn)程資源的特性。
2.使用互斥量和條件變量,或使用信號(hào)量實(shí)現(xiàn)線程的同步互斥。
3.驗(yàn)證“哲學(xué)家進(jìn)餐”問(wèn)題中的死鎖情況,并加以解決。
二、準(zhǔn)備知識(shí)
一方面,請(qǐng)自學(xué)課程教材中關(guān)于線程同步的內(nèi)容。
POSIX線程函數(shù)庫(kù)(pthread)為多線程編程提供了一套支持函數(shù),這些函數(shù)在頭文獻(xiàn)P
thread.h中定義,所有多線程程序都必須包含這個(gè)頭文獻(xiàn)。由于pthread庫(kù)不是Linux系統(tǒng)
的庫(kù),所以編譯時(shí),需要用-1pthread選項(xiàng)來(lái)鏈接線程庫(kù)。
1.創(chuàng)建線程
intpthread_create(pthread_t*thread,//線程id指針
pthread_attr_t*attr,//線程屬性指針
void*(start_routine)(void*),//返回void類(lèi)型的指針函數(shù)
8。丫oid*arg);//start_routine的形參
該函數(shù)成功返回0,失敗返回非0值。
例:
/*theexamplefi1eisereatethread.c*/
#include<pthread.h>
#include<stdio.h>
void*create(void*arg)〃新線程執(zhí)行的函數(shù)
{inti;
for(i=0;i<10;i++)
printf(u%dnewthreadcreated%c\n",i,*(char*)arg);
pthread_exit(NULL);〃退出線程
)
intmain(intargc,char*argv[J)//程序從主函數(shù)開(kāi)始
pthread_tp_thread;//線程ID
intret;
chara-A1;
charb=B;
ret=pthread_create(&p_thread,NULL,create,(void*)&a);
//創(chuàng)建新線程執(zhí)行create函數(shù),傳遞參數(shù)a
create((void*)&b);//主線程執(zhí)行此函數(shù),傳遞參數(shù)b
編譯時(shí)使用命令:gcc-1pthread-ocreatethreadcreatethread.c
2.等待子線程結(jié)束
#inc1ude<pthread.h>
intpthreadJoin(pthread_tp_thread,void**status);
該函數(shù)的第一個(gè)參數(shù)是線程的ID,第二個(gè)參數(shù)為子線程返回的值,該函數(shù)返回0表達(dá)成功,
非0為失敗。下面給出“觀測(cè)者一報(bào)告者”線程并發(fā)的例子,體會(huì)多線程共享數(shù)據(jù)也許導(dǎo)致的
問(wèn)題。
#include<pthread.h>
#include<stdio.h>
staticintcount=10;
void"observer"oid*arg)//觀測(cè)者執(zhí)行的函數(shù)
{inti;
for(i=0;i<100;i++)
printf(nobserver%dcount=%d\n",i,(*(int*)arg)++);
pthread_exit(NULL);//退出線程
)
void*reporter(void*arg)//報(bào)告者執(zhí)行的函數(shù)
{inti;
for(i=0;i<100;i++)
(
printf(M%dcount=%d\nn,i,*(int*)arg);
*(int*)arg=0;
)
pthread_exit(NULL);//退出線程
)
intmain(intargc,char*argv[])//主函數(shù)
(
pthread_tpl_thread,p2—thread;//線程ID
pthread_create(&pl_thread,NULL,observer,(void*)&count);〃創(chuàng)建新線程
pthread_create(&p2_thread,NULL,reporter,(void**)&count);
pthread_Join(p1_thread,NULL);//主線程等待子線程結(jié)束
pthread_join(p2—thread,NULL);
)
3.互斥鎖
互斥鎖可以解決線程之間互斥訪問(wèn)資源的問(wèn)題。當(dāng)一個(gè)線程鎖定一個(gè)互斥量后,可以執(zhí)行臨
界區(qū),而此時(shí)另一個(gè)線程若要鎖定互斥量,將被掛起,直到前一個(gè)線程解鎖該互斥量后,后
一個(gè)線程才干再次鎖定互斥量,并進(jìn)入臨界區(qū)訪問(wèn)。創(chuàng)建互斥量前,必須先聲明一個(gè)類(lèi)型為
Pthread_mutex_t的變量,并對(duì)它初始化,例如:
pthread_nutex_t=PTHREAD_MUTEX_INITIALIZER;//該初始化可創(chuàng)建一
個(gè)快速互斥量
下面三個(gè)函數(shù)分別用來(lái)鎖定互斥量,解鎖互斥量以及銷(xiāo)毀互斥量
intpthread_mutex_lock(pthread_mutex_t*mutex);
intpthread_mutex_unlock(pthread_mutex_t*mutex);
intpthread_mutex_destroy(pthread_mutex_t*mutex);
三個(gè)函數(shù)執(zhí)行對(duì)的時(shí),返回0。
4.條件變量
通常互斥量與條件變量同時(shí)使用,用互斥量實(shí)現(xiàn)線程互斥,用條件變量實(shí)現(xiàn)線程間的同步。條
件變量是一種使線程等待某些事件發(fā)生的機(jī)制。線程等待一個(gè)條件變量,直到另一個(gè)線程給
該條件變量發(fā)送一個(gè)信號(hào)將該線程喚醒。
(1)創(chuàng)建條件變量
創(chuàng)建條件變量時(shí),必須先聲明一個(gè)類(lèi)型為pthread_cond_t類(lèi)型的變量,并進(jìn)行初始化。可
以簡(jiǎn)樸地使用一個(gè)宏P(guān)THREAD_CONDJNITIALIZER或調(diào)用pthread_cond_ini
t()函數(shù)。
例如:pthread_cond_tgot_request=PTHREAD_COND_INITIALIZER
需要注意的是,PTHREAD_COND」NEALIZER是一個(gè)結(jié)構(gòu),只能在條件變量聲明時(shí)對(duì)它
進(jìn)行初始化,運(yùn)營(yíng)時(shí)對(duì)條件變量初始化必須使用pthread_cond_init()函數(shù)。
(2)向條件變量發(fā)信號(hào)
向條件變量發(fā)出信號(hào),可以喚醒等待這個(gè)條件變量的一個(gè)線程或所有線程(廣播方式),使用下
面兩個(gè)函數(shù)可以實(shí)現(xiàn):
intpthread_cond_signa1(&got_request);//got_request是一個(gè)已經(jīng)對(duì)的初
始化的條件變量
intpthread_cond_broadcast(&got_request);〃廣播函數(shù)
成功時(shí)返回0,失敗時(shí)返回非0值。
(3)守候條件變量
pthread_cond_wait(pthread_cond_t*restrictcond,pthread_mutex_t*re
strictmutex);
pthread_cond_timewait(pthread_cond_t*restrictcond,pthread
_mutex_t*restrictmutex,conststructtimespec*restrictabstime);
這兩個(gè)函數(shù)將使調(diào)用線程阻塞在條件變量上,并解鎖互斥量(為避免競(jìng)爭(zhēng)使用條件變量,在守
候條件變量前必須加鎖互斥量),第二個(gè)函數(shù)中,允許用戶(hù)給定一個(gè)超時(shí)間隔,過(guò)了時(shí)間間
隔,函數(shù)就返回,返回值為ETIMEDOUT。而第一個(gè)函數(shù)若沒(méi)有收到信號(hào)將一直等下去。
進(jìn)一步說(shuō)明上述兩個(gè)守候條件變量的函數(shù):在守候條件變量前,先對(duì)互斥量加鎖,然后調(diào)用守
候函數(shù),這時(shí),線程阻塞去等候條件,并解鎖互斥量,之后,當(dāng)某個(gè)線程向這個(gè)條件變量發(fā)出
信號(hào)便會(huì)喚醒等候的線程。
(4)銷(xiāo)毀條件變量
intpthread_cond_destory(pthread_cond_t*cond);
成功時(shí)返回0,失敗時(shí)返回非0值。
三、程序框架
#inc1ude<pthread.h>
#include<stdio.h>
#include<errno.h>j............〃聲明條件變量和互斥量,以及線程共享的數(shù)據(jù)
voidP()j{
pthread_mutex_lock();j........
pthread_cond_wait();//等待條件變量
pthread_mutex_un1ock();j........
voidV()j{pthread_mutex_1ock();
pthread_cond_signal();jpthread_mutex_unlock();j}
void*create(void*arg)〃新線程執(zhí)行的函數(shù)乂intph—no;〃哲學(xué)家編
號(hào)
ph_no=*(int*)arg;
........jP(ph_no);
P((ph_no+l)%5);
printf("theno%dphilosopherdining\n",ph—no);
V(ph_no);jV((ph—no+1)%5);jpthread_exit(NULL);
}jmain()
(
pthread_tp_thread[5];〃線程ID
intph_no[5],ret,i;〃ph_no為哲學(xué)家編號(hào),
pthread_create();///創(chuàng)建5個(gè)哲學(xué)家線程
}“
6課題五基于消息緩沖通信實(shí)現(xiàn)客戶(hù)進(jìn)程與服務(wù)者進(jìn)程間的通信
一、目的
學(xué)習(xí)SystemV的進(jìn)程間通信機(jī)制,使用消息緩沖通信實(shí)現(xiàn)多個(gè)客戶(hù)進(jìn)程和一個(gè)服務(wù)進(jìn)程之
間的通信。具體規(guī)定:
1.創(chuàng)建多個(gè)客戶(hù)進(jìn)程,以及一個(gè)服務(wù)進(jìn)程。
2.創(chuàng)建兩個(gè)公共消息隊(duì)列,一個(gè)用于客戶(hù)進(jìn)程向服務(wù)進(jìn)程發(fā)送請(qǐng)求,一個(gè)用于服務(wù)進(jìn)程向
客戶(hù)進(jìn)程返回結(jié)果。
3.客戶(hù)進(jìn)程發(fā)送請(qǐng)求,并阻塞接受結(jié)果,服務(wù)進(jìn)程接受請(qǐng)求并完畢服務(wù)后返回結(jié)果給相應(yīng)的客
戶(hù)進(jìn)程。
二、準(zhǔn)備知識(shí)
一方面,請(qǐng)復(fù)習(xí)課程教材中關(guān)于消息緩沖通信的內(nèi)容。
消息緩沖所涉及的系統(tǒng)調(diào)用如下:
1.建立消息隊(duì)列
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
intmsqid=msgget(key_tkey,intmsgf1g);
其中,key是消息隊(duì)列的關(guān)鍵字,是通信雙方約定的一個(gè)長(zhǎng)整型數(shù)。key有以下兩個(gè)取值:
(1)IPC_PRIVATE:表達(dá)建立一個(gè)私有消息隊(duì)列。
(2)正整數(shù):表達(dá)建立一個(gè)公共的消息隊(duì)列。
Msgflg是消息隊(duì)列的創(chuàng)建方式,有兩個(gè)取值,這兩個(gè)值可以單獨(dú)使用,也可用“或”位運(yùn)算符連
起來(lái)使用:
(1)IPC_CREAT:創(chuàng)建一個(gè)key所代表的新消息隊(duì)列,類(lèi)似于create。
(2)IPC_EXCL:同IPC_CREAT同時(shí)使用時(shí),若key相應(yīng)消息隊(duì)列存在,則返回一1,并
將錯(cuò)誤指示變量errno置EEXIST,單獨(dú)使用時(shí)無(wú)意義。
此外,還可以設(shè)立消息隊(duì)列的存取權(quán)限。調(diào)用該消息隊(duì)列系統(tǒng)調(diào)用時(shí),若key=O,則創(chuàng)建一
個(gè)消息隊(duì)列,若keyWO,在消息隊(duì)列中查找關(guān)鍵字是key的消息隊(duì)列,假如找到,且有權(quán)訪問(wèn),
則返回消息隊(duì)列標(biāo)記,假如無(wú)權(quán)訪問(wèn)則犯錯(cuò)返回,假如沒(méi)有找到,且msgf1g具有IPC_CRE
AT標(biāo)志,則創(chuàng)建一個(gè)消息隊(duì)列,并返回消息隊(duì)列標(biāo)記。
例如:msqid=msgget(123,0600|IPC_CREAT|IPC_EXCL);
注意:這里0600表達(dá)對(duì)該消息隊(duì)列的存取權(quán)限,設(shè)立的方式同文獻(xiàn)存取權(quán)限的設(shè)立一致。06
00表達(dá)對(duì)消息隊(duì)列的創(chuàng)建者具有讀寫(xiě)權(quán)限,對(duì)同組用戶(hù)和其他用戶(hù)無(wú)任何權(quán)限。
2.向消息隊(duì)列發(fā)送消息
#inc1ude<sys/msg.h>
intmsgsnd(intmsqid,void*msgp,size_tmsgsz,intmsgflg);
其中,msqid是消息隊(duì)列標(biāo)記,msgp是指向用戶(hù)區(qū)要發(fā)送的消息的指針,msgsz是要發(fā)送
的消息正文的字節(jié)數(shù),msgflg是同步標(biāo)志,當(dāng)發(fā)送消息的某個(gè)條件不滿(mǎn)足時(shí),若msgflg
中的IPC_N0WAIT標(biāo)志未設(shè)立(即=0),發(fā)送進(jìn)程阻塞等待,直到將消息掛入消息隊(duì)列,若IPC
_NOWAIT標(biāo)志已設(shè)立,發(fā)送進(jìn)程立即返回。
該函數(shù),成功時(shí)返回實(shí)際發(fā)送的字節(jié)數(shù),錯(cuò)誤時(shí)返回一1。
3.接受消息
#inc1ude<sys/msg.h>
intmsgrcv(intmsqid,void*msgp,size_tmsgsz,1ongmsgtyp,int
msgflg);
其中,msqid是消息隊(duì)列標(biāo)記,msgp是指向用戶(hù)接受消息的指針,msgsz是要接受的消息
正文的字節(jié)數(shù),msgf1g是同步標(biāo)志,當(dāng)接受消息的某個(gè)條件不滿(mǎn)足時(shí),若msgflg中的IPC_
NOWAIT標(biāo)志未設(shè)立(即=0),接受進(jìn)程阻塞等待,直到接受到消息為止,若IPJN0WAIT
標(biāo)志已設(shè)立,接受進(jìn)程立即返回。Msgtyp是要接受的消息類(lèi)型,msgtyp=0,表達(dá)接受消息隊(duì)
列中的第一個(gè)消息,若msgtyp>0,則接受消息隊(duì)列中與msgtyp相同的第一個(gè)消息,若m
sgtypV0,則接受消息隊(duì)列中類(lèi)型值小于msgtyp絕對(duì)值且類(lèi)型值最小的消息。
該函數(shù)成功時(shí),返回接受消息的正文長(zhǎng)度,錯(cuò)誤時(shí),返回T。
三、程序框架
系統(tǒng)規(guī)定最少設(shè)立三個(gè)客戶(hù)進(jìn)程,一個(gè)服務(wù)進(jìn)程,客戶(hù)進(jìn)程將請(qǐng)求(四則運(yùn)算)提交給服務(wù)進(jìn)
程,服務(wù)進(jìn)程從消息隊(duì)列1接受后進(jìn)行服務(wù)(進(jìn)行運(yùn)算,求得四則運(yùn)算表達(dá)式的結(jié)果),將結(jié)
果發(fā)送到消息隊(duì)列2,客戶(hù)進(jìn)程從消息隊(duì)列2接受屬于自己的結(jié)果。
//clientl.c
#include<sys/types.h>
#include<sys/ipc.h>
#inc1ude<sys/msg.h>
#defineSDKEY75〃SDKEY是發(fā)送請(qǐng)求的消息隊(duì)列關(guān)鍵字,是一個(gè)公共消息隊(duì)列
#defineRVKEY76//RVKEY是接受結(jié)果的消息隊(duì)列關(guān)鍵字,也是一個(gè)公共消息隊(duì)列
structmsgform(//消息的格式
longmtype;/*消息類(lèi)型*/
charmtext[N];/*消息正文*/
//client2.c
//c1ient3.c
//server.c
課題六銀行家算法模擬
一、目的
1.加深了解資源申請(qǐng)、避免死鎖等概念。
2.體會(huì)避免死鎖的具體實(shí)行方法——銀行家算法的實(shí)現(xiàn)過(guò)程。
3.進(jìn)一步提高軟件開(kāi)發(fā)能力。
二、規(guī)定
1.復(fù)習(xí)銀行家算法,設(shè)計(jì)一個(gè)具有若干(不少于3種)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年數(shù)字水位儀項(xiàng)目申請(qǐng)報(bào)告
- 2025年國(guó)土資源普查核儀器項(xiàng)目申請(qǐng)報(bào)告模范
- 2024-2025學(xué)年西藏那曲市巴青縣三上數(shù)學(xué)期末統(tǒng)考試題含解析
- 軍訓(xùn)心得體會(huì)匯編15篇
- 2025年水上加油船項(xiàng)目規(guī)劃申請(qǐng)報(bào)告模板
- 2025年放射性廢氣處置設(shè)備項(xiàng)目申請(qǐng)報(bào)告
- 2022裝修監(jiān)理年終工作總結(jié)
- 去超市實(shí)習(xí)報(bào)告范文8篇
- 住房申請(qǐng)書(shū)模板10篇
- 演講競(jìng)聘演講稿范文6篇
- 電化學(xué)儲(chǔ)能電站檢修規(guī)程
- 嵌入式系統(tǒng)智慧醫(yī)療應(yīng)用技術(shù)研究
- 2024年云南昆明尋甸城鄉(xiāng)投資開(kāi)發(fā)集團(tuán)有限公司招聘筆試參考題庫(kù)含答案解析
- MOOC 家具·設(shè)計(jì)·生活-北京林業(yè)大學(xué) 中國(guó)大學(xué)慕課答案
- 黑龍江省哈爾濱市香坊區(qū)2023-2024學(xué)年八年級(jí)上學(xué)期期末語(yǔ)文試卷
- 教師職業(yè)道德與專(zhuān)業(yè)發(fā)展智慧樹(shù)知到期末考試答案2024年
- 農(nóng)村污水處理設(shè)施運(yùn)維方案特別維護(hù)應(yīng)急處理預(yù)案
- 幕墻工程專(zhuān)項(xiàng)施工方案審批流程
- 新視野英語(yǔ)教程(第四版)讀寫(xiě)教程1 期末測(cè)試卷 測(cè)試卷A
- 【施工組織方案】框架結(jié)構(gòu)施工組織設(shè)計(jì)
- 人工智能背景下高校智慧思政建設(shè)
評(píng)論
0/150
提交評(píng)論