版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第二講多進(jìn)程程序設(shè)計本章內(nèi)容2.1
進(jìn)程的基本概念和特點2.2進(jìn)程的控制2.3信號(signal)2.4進(jìn)程間通信(進(jìn)程協(xié)作的橋梁)2.1進(jìn)程的概念和特點
進(jìn)程:執(zhí)行中的程序。系統(tǒng)中的每一個進(jìn)程都運行在上下文(context)中。
上下文:由程序正確運行所需要的狀態(tài)組成,包括:
存放在內(nèi)存中的代碼和數(shù)據(jù)
堆棧、寄存器內(nèi)容、程序計數(shù)器、環(huán)境變量、文件描述符一、進(jìn)程相關(guān)的概念演示
上下文切換:就是從一個可執(zhí)行進(jìn)程切換到另一個可執(zhí)行進(jìn)程。引發(fā)上下文切換的原因:
I/Orequest:ProcessisplacedonI/OqueueforadeviceSpawnandwait:Sometimeswhenaprocesscreatesanewprocess,itmustwaituntilthechildcompletes
TimesliceexpirationSleeprequest
系統(tǒng)調(diào)用:由操作系統(tǒng)提供的應(yīng)用程序編程接口(API)。用戶空間內(nèi)核
進(jìn)程地址空間:虛擬地址0~2n-1,每個進(jìn)程都有自己私有的地址空間,一個進(jìn)程不可以直接訪問另外一個進(jìn)程的地址空間。(1)
一個進(jìn)程可以包括多個線程;(2)線程間共享地址空間,因此,一個線程修改一個變量(全局或靜態(tài)),其它線程都能獲知;(3)線程間通信直接通過共享變量,而進(jìn)程間通信則需要通過管道、消息隊列等;二、進(jìn)程與線程區(qū)別獨享地址空間共享地址空間Sharedmemorysegments,pipes,openfilesormmap’dfilesDATASTACKTEXTDATASTACKTEXTprocessesSharedMemorymaintainedbykernelprocesses三、進(jìn)程間通信模型#include<sys/types.h>#include<unistd.h>pid_tgetpid(void);pid_tgetppid(void);獲取進(jìn)程ID2.2進(jìn)程控制調(diào)用者進(jìn)程ID
每一個進(jìn)程都有唯一的非零正數(shù)ID(PID)調(diào)用者父進(jìn)程進(jìn)程ID一、進(jìn)程ID#include<stdlib.h>voidexit(intstatus);exit函數(shù)調(diào)用exit函數(shù),主動退出運行
進(jìn)程終止的三種方式:(1)收到一個信號,信號的默認(rèn)行為是終止運行;(2)從主程序返回;(3)調(diào)用exit函數(shù);二、進(jìn)程終止#include<sys/types.h>#include<unistd.h>pid_tfork(void);創(chuàng)建子進(jìn)程三、進(jìn)程創(chuàng)建“fork”:把當(dāng)前進(jìn)程復(fù)制出一個新的進(jìn)程,當(dāng)前的進(jìn)程就是新進(jìn)程的父進(jìn)程,新進(jìn)程稱為子進(jìn)程。
intglob=6;intmain(){
pid_t
pid; intx=1; pid=fork(); if(pid==0){
glob++; printf(“child:glob=%d,x=%d\n”,
glob,++x); exit(0); } printf(“parent:glob=%d,x=%d\n”,
glob,--x);}示例
子進(jìn)程
父進(jìn)程如果沒有exit演示intglob=6;intmain(){
pid_t
pid; intx=1; pid=fork(); if(pid<0){ printf(“%s\n”,strerror(errno)); }elseif(pid==0){
glob++; printf(“child:glob=%d,x=%d\n”,
glob,++x); }else{ printf(“parent:glob=%d,x=%d\n”,
glob,--x); }}示例2
子進(jìn)程
父進(jìn)程調(diào)用一次,返回兩次(1)返回到父進(jìn)程;并發(fā)執(zhí)行fork(2)返回到新創(chuàng)建的子進(jìn)程;(1)宏觀上,父子進(jìn)程并發(fā)執(zhí)行;(2)微觀上(多核系統(tǒng)),可能是交替執(zhí)行或者并行執(zhí)行;fork相同但是獨立的地址空間(1)復(fù)制:相同的用戶棧、相同的本地變量、相同的堆、相同的全局變量……;(2)獨立:父子進(jìn)程都有獨立的私有地址空間,對變量的任何更改不會影響另外一個進(jìn)程對應(yīng)的變量;文件共享父進(jìn)程打開的文件描述符,子進(jìn)程可以繼續(xù)使用;多次調(diào)用fork?intmain()
{
fork(); printf(“hello\n”); exit(0);}1次forkhellohello進(jìn)程圖演示intmain()
{
fork(); fork(); printf(“hello\n”); exit(0);}2次演示helloforkhellohellohello進(jìn)程圖forkintmain()
{
fork(); fork(); fork(); printf(“hello\n”); exit(0);}3次演示進(jìn)程圖hellohellohellohellohelloforkforkhellohellohelloforkintmain()
{ pid_tpid1,pid2;
pid1=fork(); if(pid1>0){ pid2=fork();
if(pid2>0){ fork();
}
}
printf(“hello\n”); exit(0);}3次演示forkhello進(jìn)程圖hellohellohelloforkforkintmain()
{
while(1)
fork();
printf(“hello\n”); exit(0);}forkbombpid_tcreateChild(){pid_tpid=fork();if(pid==0){
printf("childdosomethinghere!\n");
exit(0);
}
returnpid;
}intmain(){pid_tchildPid;
inti,procNum=3;for(i=0;i<procNum;i++){
childPid=createChild();
}
exit(0);
}進(jìn)程扇子子子父四、子進(jìn)程回收子進(jìn)程先于父進(jìn)程終止運行,但是尚未被父進(jìn)程回收,內(nèi)核并未清除該進(jìn)程,保持在一種已終止?fàn)顟B(tài),該進(jìn)程稱為“僵尸進(jìn)程(僵死進(jìn)程)”
演示:zombie.c父進(jìn)程正在運行僵尸進(jìn)程父進(jìn)程長時間執(zhí)行時,必須回收子進(jìn)程父進(jìn)程先退出演示:parent_exit.c#include<sys/types.h>#include<sys/wait.h>pid_twait(int*status);pid_twaitpid(pid_tpid,int*status,intoptions);回收子進(jìn)程wait:父進(jìn)程阻塞,直到一個子進(jìn)程運行結(jié)束。
退出狀態(tài)WIFEXITED(status)WEXITSTATUS(status)WIFSTOPPED(status)WSTOPSIG(status)WIFCONTINUED(status):sincelinux2.6.10WIFSIGNALED(status)WTERMSIG(status)WCOREDUMP(status)演示:example_waitvoidwait_exit(int
status){ if(WIFEXITED(status))
printf("normaltermination,exitstatus=%d\n", WEXITSTATUS(status));
elseif(WIFSIGNALED(status))
printf("abnormaltermination,signalnumber= %d%s\n",WTERMSIG(status),#ifdefWCOREDUMP
WCOREDUMP(status)?"(corefilegenerated)":"");#else
"");#endif elseif(WIFSTOPPED(status))
printf(“childstopped,signalnumber=%d\n”, WSTOPSIG(status));}正常退出退出狀態(tài)解析非正常退出暫停(掛起)演示:wait_exit.c#include<sys/types.h>#include<sys/wait.h>pid_twait(int*status);pid_twaitpid(pid_tpid,int*status,intoptions);回收子進(jìn)程waitpid:比wait更加靈活,可以是非阻塞的。
0:阻塞,即掛起調(diào)用進(jìn)程;WNOHANG:非阻塞,即如果指定的子進(jìn)程都還沒有終止運行,立即返回0;否則返回,終止運行進(jìn)程ID;WUNTRACED:如果子進(jìn)程掛起,則立即返回;默認(rèn)只返回終止運行的進(jìn)程;WUNTRACED|WNOHANG:pid>0: 等待進(jìn)程id為pid的子進(jìn)程。
pid==0: 等待與自己同組的任意子進(jìn)程。
pid==-1: 等待任意一個子進(jìn)程
pid<-1: 等待進(jìn)程組號為-pid的任意子進(jìn)程。參數(shù):pid_tpid參數(shù):intoptionswait(&stat)等價于waitpid(-1,&stat,0)#include<unistd.h>intexecve(constchar*path,constchar*argv[],constchar*envp[]);執(zhí)行新程序啟動一個新的程序,新的地址空間完全覆蓋當(dāng)前進(jìn)程的地址空間五、執(zhí)行一個新程序path:執(zhí)行文件argv:參數(shù)表envp:環(huán)境變量表,一般直接用environ就行參數(shù)char*argv[]={“gcc”,“-g”,“-c”,“fork.c”,NULL};execve(“/usr/bin/gcc”,argv,environ);例環(huán)境變量:在操作系統(tǒng)中用來指定操作系統(tǒng)運行環(huán)境的一些參數(shù)演示:example_execve.c如何設(shè)計程序自動評判系統(tǒng)Web編程:
通過HTTP協(xié)議上傳源代碼文件至服務(wù)器1)守護(hù)進(jìn)程fork出子進(jìn)程;2)子進(jìn)程內(nèi)調(diào)execve,執(zhí)行g(shù)cc基本方法1.源代碼上傳2.編譯源代碼char*argv[]={“gcc”,“-o”,“3906”,“3906.c”,“-O2”NULL};execve(“gcc”,argv,environ);1)守護(hù)進(jìn)程fork出子進(jìn)程;2)子進(jìn)程內(nèi)調(diào)execve,執(zhí)行38063)調(diào)用waitpid:
a)等待子進(jìn)程結(jié)束
i)父進(jìn)程計時,如果子進(jìn)程在2秒內(nèi)不結(jié)束
,父進(jìn)程kill-9pid b)獲取結(jié)束狀態(tài)
i)正常終止 ii)非正常終止:
SIGSEGV、
SIGFPE
3.執(zhí)行pid_tpid=fork();if(pid==0){ execv(“./3906”,argv,environ); exit(0);}開始計時intstatus;while(waitpid(pid,&status,WNOHANG){
if(超過規(guī)定時間) kill(pid);}status,檢查退出狀態(tài),錯誤原因3.執(zhí)行偽代碼
老師您好,
請問這段程序有什么問題?(作業(yè)的編程題的最后一題)
#include<stdio.h>
main()
{
intn,s=0,i=1;
scanf("%d",&n);
while(i<n+1)
{
s=s+i*(i+1)/2;
i=i++;
}
printf("%d\n",s);
return0;
}
為什么系統(tǒng)判定我運行時間過長?
謝謝您.
addl$1,-8(%ebp)
movl-12(%rbp),%edx
leaq-12(%rbp),%rax
incl(%rax)
movl%edx,-12(%rbp)
2.3信號(signals)
信號:也稱作軟中斷,是Linux操作系統(tǒng)用來通知進(jìn)程發(fā)生了某種異步事件的一種手段。例常見信號前臺程序執(zhí)行過程中按下Ctrl-c就會向它發(fā)出SIGINT信號,默認(rèn)終止進(jìn)程SIGINTSIGKILL
SIGTERMSIGALRMSIGCHLDSIGSEGV立即中止進(jìn)程,不能被捕獲或忽略kill命令默認(rèn)的中止程序信號定時器到期,可用alarm函數(shù)來設(shè)置定時器。默認(rèn)動作終止進(jìn)程子進(jìn)程終止或停止,默認(rèn)動作為忽略無效的內(nèi)存引用演示:sigsegv.c信號檢測與處理流程用戶空間內(nèi)核空間用戶進(jìn)程異常(系統(tǒng)調(diào)用、中斷(時間片到期)、故障、終止)異常處理(系統(tǒng)調(diào)用、中斷處理等)檢測到信號信號處理返回到內(nèi)核用戶進(jìn)程一、發(fā)送信號信號發(fā)送起因內(nèi)核通過更新目的進(jìn)程上下文的某個狀態(tài)(pending位向量,blocked位向量),來實現(xiàn)信號的發(fā)送。內(nèi)核檢測到一個系統(tǒng)事件:除零、子進(jìn)程終止、非法內(nèi)存引用一個進(jìn)程調(diào)用了kill函數(shù):顯式要求內(nèi)核向目的進(jìn)程發(fā)送信號,目的進(jìn)程可以是調(diào)用進(jìn)程自身#include<sys/types.h>
#include<signal.h>intkill(pidtpid,intsig);kill函數(shù)#include<unistd.h>unsignedintalarm(unsignedintsecs);alarm函數(shù)向其它進(jìn)程(包括自己)發(fā)送信號給自己發(fā)送時鐘信號(SIGALRM)信號發(fā)送函數(shù)例1intmain(){pid_tpid;
/*childsleepsuntilSIGKILLsignalreceived,thendies*/
if((pid=fork())==0){
pause();
/*waitforasignaltoarrive*/printf("controlshouldneverreachhere!\n");exit(0);}
/*parentsendsaSIGKILLsignaltoachild*/
kill(pid,SIGKILL);exit(0);}子進(jìn)程sleep,只有信號才能將其喚醒父進(jìn)程向子進(jìn)程發(fā)信號演示:example_kill.c例2intmain(){
alarm(5);
/*nextSIGALRMwillbedeliveredin5s*/while(1){;/*signalhandlerreturnscontrolhereeachtime*/}exit(0);}給自己發(fā)信號演示:example_alarm信號處理忽略信號:SIGSTOP與SIGKILL除外捕獲信號:通過系統(tǒng)調(diào)用,自定義接收到信號后采取的行動。SIGSTOP與SIGKILL除外執(zhí)行信號的默認(rèn)動作當(dāng)進(jìn)程接收到一個信號(可能是自己發(fā)出,也可能是別的有權(quán)限的進(jìn)程發(fā)出),它可以采取的動作可以是下面任意一種:二、接收信號#include<signal.h>typedefvoid(*sighandler_t)(int);
sighandler_tsignal(intsignum,sighandler_thandler);信號捕捉函數(shù)指針回調(diào)函數(shù)(callbackfunction)#include<signal.h>intsigaction(intsignum,structsigaction*act,structsigaction*oldact);信號捕捉typedefvoid(sighandler_t)(int);
sighandler_t*signal(intsignum,sighandler_t*handler);例intmain(){
signal(SIGALRM,handler);
alarm(5);
/*nextSIGALRMwillbedeliveredin5s*/ while(1){;/*signalhandlerreturnscontrolhereeachtime*/ } exit(0);}安裝信號處理函數(shù)voidhandler(intsig){staticintbeeps=0;printf("BEEP\n");if(++beeps<5)
/*1秒后再次發(fā)送信號*/
alarm(1);
else{
printf("BOOM!\n");
exit(0);
}
}演示:example_alarm_handler例intmain(){pid_tpid;
/*子進(jìn)程內(nèi)安裝信號處理函數(shù)*/
if((pid=fork())==0){
signal(SIGTERM,handler);
signal(SIGINT,handler);while(1)
pause();
}
/*父進(jìn)程向子進(jìn)程發(fā)送信號
*/
sleep(2);
kill(pid,SIGINT);
sleep(2);
kill(pid,SIGTERM);
}voidhandler(intsig){/*只有收到SIGTERM信號才終止運行*/
if(sig==SIGTERM){printf("Catchsignal SIGTERM\n"); exit(0);}else{printf("Sorry!youaresignal %d,iwillnotexit!\n",sig);}
}演示:example_kill_handler#include<signal.h>intsigprocmask(inthow,constsigset_t*set,sigset_t*oldset);intsigemptyset(sigset_t*set);
intsigfillset(sigset_t*set);
intsigaddset(sigset_t*set,intsignum);
intsigdelset(sigset_t*set,intsignum);
intsigismember(constsigset_t*set,intsignum);信號阻塞函數(shù)信號阻塞可以阻塞或者取消阻塞
信號阻塞:目的進(jìn)程接收但是不處理該信號,直到取消阻塞。實現(xiàn):blocked位向量存放被阻塞信號intsign=0;intmain(){pid_tpid;if((pid=fork())==0){
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器
while(sign==0);//原地踏步程序;
sign=0;//還原sign值
kill(getppid(),SIGUSR1);//給父進(jìn)程發(fā)信號
exit(0);
}
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器//here,dosomething
kill(pid,SIGUSR1);
while(sign==0);//原地踏步程序,等待子進(jìn)程的接受確認(rèn)消息
sign=0;//還原sign值
}voidreceive(intsigno){ printf(“pid=%d,received\n”,getpid()); sign=1;
}例
子進(jìn)程演示:example_badsig
父進(jìn)程執(zhí)行結(jié)果intsign=0;intmain(){pid_tpid;if((pid=fork())==0){
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器
while(sign==0);//原地踏步程序;
sign=0;//還原sign值
kill(getppid(),SIGUSR1);//給父進(jìn)程發(fā)信號
exit(0);
}
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器//here,dosomething
kill(pid,SIGUSR1);
while(sign==0);//原地踏步程序,等待子進(jìn)程的接受確認(rèn)消息
sign=0;//還原sign值
}
子進(jìn)程
父進(jìn)程執(zhí)行結(jié)果:主進(jìn)程永遠(yuǎn)“忙等”子進(jìn)程在signal之前,收到了父進(jìn)程發(fā)來的SIGUSR1信號
SIGUSR1的默認(rèn)行為時終止運行intsign=0;intmain(){pid_tpid;if((pid=fork())==0){
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器
while(sign==0);//原地踏步程序;
sign=0;//還原sign值
kill(getppid(),SIGUSR1);//給父進(jìn)程發(fā)信號
exit(0);
}
signal(SIGUSR1,receive);//注冊SIGUSR1的響應(yīng)器//here,dosomethingkill(pid,SIGUSR1);
while(sign==0);//原地踏步程序,等待子進(jìn)程的接受確認(rèn)消息
sign=0;//還原sign值
}
子進(jìn)程
父進(jìn)程正確的程序sigemptyset(&chldmask);sigaddset(&chldmask,SIGUSR1);sigprocmask(SIG_BLOCK,&chldmask,&savemask);阻塞SIGUSR1信號,即,如果收到SIGUSR1信號,不做處理,放到block位向量內(nèi)sigprocmask(SIG_SETMASK,&savemask,NULL);取消SIGUSR1信號阻塞,即,將block位向量的信號,放到pending向量,并調(diào)用相應(yīng)的信號處理函數(shù)sigprocmask(SIG_SETMASK,&savemask,NULL);取消SIGUSR1信號阻塞,即,將block位向量的信號,放到pending向量,并調(diào)用相應(yīng)的信號處理函數(shù)演示:example_sigmask2.4進(jìn)程間通信(interprocesscommunication)
進(jìn)程間通信(IPC):多個進(jìn)程間協(xié)作或溝通的橋梁。管道
消息隊列
socket
共享內(nèi)存
信號量
記錄鎖DATASTACKTEXTDATASTACKTEXTprocessesmaintainedbykernelprocesses進(jìn)程間通信方式消息傳遞共享內(nèi)存同步最初的UNIXIPCSystemVIPC基于Socket的IPCLinuxIPCPOSIXIPCAT&TBSD最初的UnixIPC:信號(signal)、管道、FIFO;SystemVIPC:SystemV消息隊列、SystemV信號量、SystemV共享內(nèi)存;POSIXIPC:POSIX消息隊列、POSIX信號量、POSIX共享內(nèi)存
POSIX:PortableOperatingSystemInterface[forUnix]IPC進(jìn)化史主要介紹1.
POSIXmessagequeue2.POSIXSemphore
3.POSIX共享內(nèi)存anan-1a3a4a2a1…進(jìn)隊出隊隊頭元素隊尾元素先進(jìn)先出普通隊列示意圖一、消息隊列anan-1a3a4a2a1…消息消息最高優(yōu)先級入隊最早最低優(yōu)先級
入隊最晚先進(jìn)先出消息隊列(優(yōu)先級隊列)示意圖ProcesssendProcessreceive優(yōu)先級anan-1a3a4a2a1…消息消息消息隊列(優(yōu)先級隊列)示意圖ProcesssendProcessreceive隊列滿1阻塞2失敗返回(非阻塞)特殊情況1發(fā)送進(jìn)程anan-1a3a4a2a1…消息消息消息隊列(優(yōu)先級隊列)示意圖ProcesssendProcessreceive隊列空1阻塞2失敗返回(非阻塞)特殊情況2接收進(jìn)程POSIX消息隊列可能實現(xiàn)headmq_maxmsgmq_maxsizenextpriority=30datanextpriority=20dataNULLpriority=10datalength=1length=2length=3消息隊列屬性優(yōu)先級變長消息#include<mqueue.h>
#include<sys/stat.h>
#include<fcntl.h>mqd_tmq_open(constchar*name,intoflag);mqd_tmq_open(constchar*name,intoflag,
mode_tmode,structmq_attr*attr);
打開消息隊列消息隊列操作 O_RDONLY O_WRONLY O_RDWRO_NONBLOCKO_CREATO_EXCL|打開已經(jīng)
存在的隊列創(chuàng)建新
的隊列參數(shù):int
oflag
以/開頭的字符串。除了開頭的/,字符串內(nèi)不能包含/
參數(shù):const
char*namestructmq_attr{
longmq_flags;/*Flags:0orO_NONBLOCK*/
longmq_maxmsg;/*Max.#ofmessagesonqueue*/
longmq_msgsize;/*Max.messagesize(bytes)*/
longmq_curmsgs;/*#ofmessagescurrentlyinqueue*/};
參數(shù):
struct
mq_attr*attr創(chuàng)建的時候只有這兩個
成員起作用attr可以是
NULLmode宏值(8進(jìn)制)涵義S_IRUSR00400用戶讀【文件owner具有讀權(quán)限】S_IWUSR00200用戶寫S_IXUSR00100用戶執(zhí)行S_IRGRP00040組讀【與owner同組的用戶具有讀權(quán)限】S_IWGRP00020組寫S_IXGRP00010組執(zhí)行S_IROTH00004其他讀【其他用戶具有讀權(quán)限】S_IWOTH00002其他寫S_IXOTH00001其他執(zhí)行文件訪問權(quán)限常用權(quán)限設(shè)置
普通文件: 0644
可執(zhí)行文件:
0755
文件夾: 0751參數(shù):mod_tmod例structmq_attrattr;attr.mq_maxmsg=10;attr.mq_msgsize=100;attr.mq_flags=0;mqd_tmqdes=mq_open(“/zch”,O_RDWR|O_CREAT, 0664,&attr);if(mqdes<0){ printf(“%s\n",strerror(errno)); exit(-1);
}創(chuàng)建隊列例mqd_tmqdes=mq_open(“/zch”,O_RDONLY);if(mqdes<0){ printf(“%s\n",strerror(errno)); exit(-1);
}打開隊列(用于接收消息)#include<mqueue.h>intmq_getattr(mqd_tmqdes,structmq_attr*attr);intmq_setattr(mqd_tmqdes,structmq_attr*newattr, structmq_attr*oldattr);隊列屬性獲取
隊列屬性設(shè)置
隊列屬性structmq_attr{
longmq_flags;/*Flags:0orO_NONBLOCK*/
longmq_maxmsg;/*Max.#ofmessagesonqueue*/
longmq_msgsize;/*Max.messagesize(bytes)*/
longmq_curmsgs;/*#ofmessagescurrentlyinqueue*/};
#include<mqueue.h>intmq_send(mqd_tmqdes,constchar*msg_ptr, size_tmsg_len,unsignedintmsg_prio);發(fā)送消息msg_ptr: 發(fā)送的消息緩沖區(qū)(傳入)msg_len: 消息實際長度(傳入)msg_prio: 消息優(yōu)先級(傳入)例如:intmsg;mq_send(mqdes,&msg,sizeof(int),0);#include<mqueue.h>ssize_tmq_receive(mqd_tmqdes,char*msg_ptr, size_tmsg_len,unsignedint*msg_prio);接收消息msg_ptr: 接收到的消息緩沖區(qū)(傳入)msg_len: 消息緩沖區(qū)大小(傳入)msg_prio: 接收消息的優(yōu)先級(傳出)返回消息實際大小例如:charbuffer[128];ssize_tlen=mq_receive(mqdes,buffer,128,NULL);#include<mqueue.h>intmq_close(mqd_tmqdes);關(guān)閉隊列#include<mqueue.h>intmq_unlink(constchar*name);刪除隊列求深不求廣計算機學(xué)習(xí)簡單的問題(項目)深入去做理解運行機理、重視基礎(chǔ)學(xué)習(xí)程序設(shè)計復(fù)雜問題簡單化分而治之:分層次、分步驟、分階段、分任務(wù)利用你所掌握的最成熟的技術(shù)非最新、最熱門的技術(shù)不要追求一步到位程序設(shè)計是一個不斷反復(fù)、重構(gòu)的過程有深必有廣已知N,計算:例如何并行計算1.
劃分任務(wù):任務(wù)之間依賴性最小。需要做的工作1,2,3,4,5,6,7,8,9,10,11,12,13
每一個i的計算都是獨立的P1P2P3P4靜態(tài)任務(wù)分配1,2,3,4,5,6,7,8,9,10,11,12,13P1動態(tài)任務(wù)分配(能者多勞)P2P3P4P2P3P4P1P3P2P4P3P41.
劃分任務(wù):任務(wù)之間依賴性最小。2.選擇技術(shù)(動態(tài)任務(wù)分配):
父進(jìn)程利用消息隊列分任務(wù),隊列滿,阻塞;
需要做的工作
子進(jìn)程從消息隊列取任務(wù),隊列空阻塞;
回收子進(jìn)程-waitpid;子進(jìn)程1send父進(jìn)程receive12i54…3子進(jìn)程2receive例打開消息隊列設(shè)置消息隊列屬性創(chuàng)建子進(jìn)程
(=CPU數(shù))發(fā)送-1代表任務(wù)結(jié)束等待子進(jìn)程結(jié)束分配任務(wù)
(N=100000)父進(jìn)程例演示:example_mq子進(jìn)程接收任務(wù)子進(jìn)程從父進(jìn)程傳入的隊列描述符執(zhí)行計算任務(wù)接收到-1,退出循環(huán)當(dāng)多個子進(jìn)程并行執(zhí)行,同時receive消息隊列中的隊首消息時,怎么保證每個消息只被一個進(jìn)程讀取,而不會被多個讀取?問題1ssize_tmq_receive(mqd_tmqdes,char*msg_ptr, size_tmsg_len,unsignedint*msg_prio);1.對首消息拷貝到msg_ptr所指的地址,而不是對頭消息的指針賦給msg_ptr2.消息隊列receive函數(shù)內(nèi)部保證對頭消息的互斥訪問!memcpy系統(tǒng)調(diào)用從緩沖區(qū)msg_buf讀取msgSize長度的消息到recvValue。memcpy是不是一個原子操作?如何保證緩沖區(qū)msg_buf中的內(nèi)容不會被多個進(jìn)程同時讀???問題21.memcpy不是原子操作2.由于進(jìn)程的地址空間是獨立的,每一個進(jìn)程都有一個msg_buf,并不是被多個進(jìn)程共享的,所以msg_buf的內(nèi)容不會被多個進(jìn)程同時讀取。父進(jìn)程如何獲得子進(jìn)程計算結(jié)果并匯總一個隊列向子進(jìn)程發(fā)送任務(wù)用兩個消息隊列新增一個隊列接收子進(jìn)程的計算結(jié)果改進(jìn)版父進(jìn)程先刪除兩個隊列
(邊界處理)創(chuàng)建任務(wù)發(fā)送隊列創(chuàng)建任務(wù)接收隊列創(chuàng)建子進(jìn)程發(fā)送任務(wù)改進(jìn)版父進(jìn)程任務(wù)結(jié)束,告知子進(jìn)程等待子進(jìn)程結(jié)束接收子進(jìn)程計算結(jié)果改進(jìn)版子進(jìn)程子進(jìn)程接收任務(wù)從父進(jìn)程傳入的隊列描述符執(zhí)行計算任務(wù)接收到-1,退出循環(huán)計算結(jié)果發(fā)給父進(jìn)程二、信號量(namedsemaphores)信號量(semaphore):用來對共享資源進(jìn)行并發(fā)
訪問控制。例intmain(intargc,char**argv){FILE*fp;
longi,seqno=1;fp=fopen("seqno","r+");
for(i=0;i<20;i++){rewind(fp);/*rewindbeforeread*/
fscanf(fp,"%ld\n",&seqno);
printf("pid=%d,seq#=%ld\n",getpid(),seqno);seqno++;rewind(fp);/*rewindbeforewrite*/
fprintf(fp,"%ld\n",seqno);}fclose(fp);}演示:example_sem_nolock序號生成器,序號要保證唯一應(yīng)用:作業(yè)調(diào)度、打印池從文件內(nèi)
讀序號將當(dāng)前序號
寫入文件臨界區(qū)用信號量保護(hù)臨界區(qū)sem_waitcriticalregionssem_post進(jìn)程1進(jìn)程2s
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 疼痛管理模式的創(chuàng)建及評價
- 護(hù)理相關(guān)法律科普
- 互聯(lián)網(wǎng)內(nèi)容審核與規(guī)范操作
- 2026年劇本殺運營公司銀行存款結(jié)算管理制度
- 2025年鋰電池回收技術(shù)標(biāo)準(zhǔn)制定行業(yè)報告
- 2025年生物基可降解塑料生產(chǎn)項目可行性研究-技術(shù)創(chuàng)新與產(chǎn)品生命周期研究報告
- 2026年機器人手術(shù)輔助系統(tǒng)報告及未來五至十年醫(yī)療科技投資趨勢報告
- 企業(yè)的相關(guān)制度
- 產(chǎn)前會議制度
- 嚴(yán)格落實生活會制度
- 安徽省江南十校2025-2026學(xué)年高一上學(xué)期12月聯(lián)考生物(含答案)
- 杭州市臨平區(qū)2025年網(wǎng)格員招聘筆試必考題庫(含答案)
- 總裁思維培訓(xùn)課件
- 2025年信息化運行維護(hù)工作年度總結(jié)報告
- 電梯更換配件協(xié)議書
- 中海大海洋地質(zhì)學(xué)課件第12章海底礦產(chǎn)資源-1第二十二講
- 膽囊癌教學(xué)課件
- 人教版七年級上冊道德與法治期末模擬綜合測試題
- NBT 11508-2024 配電自動化工程可行性研究報告內(nèi)容深度規(guī)定
- (新交際英語2024版)英語一年級上冊全冊單元測試(含聽力音頻+解析)
- 運輸公司安全生產(chǎn)培訓(xùn)計劃
評論
0/150
提交評論