進(jìn)程和進(jìn)程間的通信_第1頁
進(jìn)程和進(jìn)程間的通信_第2頁
進(jìn)程和進(jìn)程間的通信_第3頁
進(jìn)程和進(jìn)程間的通信_第4頁
進(jìn)程和進(jìn)程間的通信_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、進(jìn)程概念;2、進(jìn)程的控制:(1) 生成一個(gè)進(jìn)程:fork(2) 進(jìn)程的同步:wait waitpid(3) 進(jìn)程的退出:exit _exit(4) 進(jìn)程“脫胎換骨”: exec函數(shù)族3、 進(jìn)程通信進(jìn)程為什么需要通信?(2) linux下進(jìn)程如何通信早期的unix通信方式無名管道;有名管道;信號sysemv的通信方式:共享內(nèi)存、消息隊(duì)列、信號量BSD的通信方式:socket4、 無名管道:適用于有血緣關(guān)系進(jìn)程通信小任務(wù)1:父進(jìn)程通過無名管道向子進(jìn)程發(fā)送字符串“Hello,youman!”,子進(jìn)程接收到后顯示出來,然后子進(jìn)程退出,最后父進(jìn)程退出。(1)創(chuàng)建子進(jìn)程:fork(2) 創(chuàng)建管道#include<unistd.h>intpipe(intpipefd[2]);參數(shù)說明(當(dāng)管道創(chuàng)建成功后):pipefd[0]:讀端的文件描述符;pipefd[l]:寫端的文件描述返回值:0表示創(chuàng)建成功,-1表示創(chuàng)建失敗(3) 父親寫管道write(4) 兒子讀管道read(5) 父親等待兒子退出wait參考代碼:#include<unistd.h>#include<stdio.h>#include<fcntl.h>#include<sys/types.h>#include<string.h>intmain(){intpid;intpipefd[2];intret;charbuf[]="Hello,youngman!";ret=pipe(pipefd);〃創(chuàng)建管道(1)if(ret<0){perror("Failedtocreatepipe:");return-1;}pid=fork();//能夠把(1)語句放此注釋的下一樣??if(pid<0){perror("Failedtocreatechildprocess:");return-1;}if(pid>0){close(pipefd[0]);〃父進(jìn)程中關(guān)閉無關(guān)的讀端write(pipefd[1],buf,strlen(buf));wait(NULL);printf("Parentprocessexit!\n");}else{charreceive_buf[100];intcount;close(pipefd[1]);〃子進(jìn)程中關(guān)閉無關(guān)的寫端count=read(pipefd[0],receive_buf,100);if(count>0){receive_buf[count]='\0';printf("Childprocessreceiveastring:%s\n",receive_buf);}printf("Childprocessexit!\n");}return0;}5、有名管道(fifo)文件系統(tǒng)中可見,可以通過mkfifo命令來創(chuàng)建一個(gè)有名管道eg:mkfifo-m0666myfifo⑵有名管道的使用跟普通文件一樣:openreadwriteclose,不用使用lseek!!!!任務(wù)2:進(jìn)程1通過有名管道把鍵盤輸入字符串發(fā)送給進(jìn)程2,進(jìn)程2收到后顯示出來,當(dāng)收到字符串“exit”是退出程序!!手工建立一個(gè)有名管道m(xù)yfifo打開管道;讀寫管道注意:有名管道的讀寫跟普通文件沒有什么區(qū)別參考代碼://fifoReader.c#include<unistd.h>#include<stdio.h>#include<fcntl.h>#include<sys/types.h>#include<string.h>intmain(){intfd;charbuf[128];fd=open("/home/gec/myfifo",O_RDONLY);if(fd<0){perror("Failedtoopenfifo:");return-1;}while(1){intcount;count=read(fd,buf,127);if(count>0){buf[count]=0;printf("fifoReaderreceiveastring:%s\n",buf);}if(strncmp(buf,"exit",4)==0){break;}}close(fd);return0;//fifoWrite.c#include<unistd.h>#include<stdio.h>#include<fcntl.h>#include<sys/types.h>#include<string.h>intmain(){intfd;charbuf[128];fd=open("/home/gec/myfifo",O_WRONLY);if(fd<0){perror("Failedtoopenfifo:");return-1;}while(1){fgets(buf,128,stdin);write(fd,buf,strlen(buf));if(strncmp(buf,"exit",4)==0){break;}}close(fd);return0;}6、信號可以用命令kill-l列出當(dāng)前系統(tǒng)所支持的信號(2)對于很多信號,進(jìn)程都有默認(rèn)的處理方式;信號的發(fā)送#include<sys/types.h>#include<signal.h>intkill(pid_tpid,intsig);信號的處理:當(dāng)進(jìn)程接收一個(gè)信號后如何與“一段代碼關(guān)聯(lián)起來”模版://信號處理函數(shù)void 你自己命名的信號處理函數(shù)名(intsig)//sig:信號值{//對信號的處理//在程序的某一個(gè)地方把信號處理函數(shù)和信號關(guān)聯(lián)起來,其“后果”就是進(jìn)程一旦接收到該信號,就會(huì)導(dǎo)致該信號處理函數(shù)的調(diào)用!#include<signal.h>typedefvoid(*sighandler_t)(int);sighandler_tsignal(intsignum,sighandler_thandler);在需要關(guān)聯(lián)的時(shí)候只需要調(diào)用signal函數(shù)就可以了!!信號:signum 信號處理函數(shù):handler小任務(wù)3:用觸發(fā)信號的方式每2秒鐘向屏幕打印“Hello,world!”⑴每隔2秒鐘觸發(fā)一個(gè)鬧鐘信號SIGALRMalarm(2);在信號處理函數(shù)里完成屏幕大打?。簐oidalarm_handler(intsig){if(sig==SIGALRM){printf(“Hello,world!\n”);\alarm(2);}}在你的程序的某個(gè)地方添加如下語句signal(SIGALRM,alarm_handler);參考代碼:#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<signal.h>voidalarm_handler(intsig){if(sig==SIGALRM){printf("Hello,world!\n");alarm(2);}}intmain(){signal(SIGALRM,alarm_handler);〃此語句的作用:一旦進(jìn)程接收到SIGALRM信號,就會(huì)導(dǎo)致alarm_handler的調(diào)用alarm(2);〃此語句的作用:2秒鐘后會(huì)向調(diào)用進(jìn)程發(fā)送SIGALRM信號while(1);return0;}小任務(wù)4:(練習(xí)kill的使用)當(dāng)進(jìn)程2收到進(jìn)程1發(fā)出的SIGUSR1信號后停止向屏幕輸出“Hello,world!\n”.進(jìn)程2的執(zhí)行格式可以如下:./進(jìn)程1 進(jìn)程2的進(jìn)程號參考代碼//p1.c#include<stdio.h>#include<unistd.h>#include<signal.h>#include<stdlib.h>intmain(intargc,char**argv){intdest_id;intret;if(argc<2){printf("Argumenttoofew!\n");return0;}dest_id=atoi(argv[1]);〃將參數(shù)指針型轉(zhuǎn)換成整型;〃sscanf(argv[1],"%d",&dest_id)迪可用這個(gè)語句實(shí)現(xiàn)數(shù)據(jù)類型轉(zhuǎn)化;printf("Thepidofdestinationprocessid%d\n",dest_id);ret=kill(dest_id,SIGUSR1);if(ret<0)printf("Failedtosendsignal.\n");return0;}//p2.c#include<stdio.h>#include<unistd.h>#include<signal.h>intflag=1;voidsigusr1_handler(intsig){if(sig==SIGUSR1){flag=0;}}intmain(){signal(SIGUSR1,sigusr1_handler);建立與信號相關(guān)聯(lián)的回調(diào)函數(shù)關(guān)系;while(flag==1){printf("Hello,world!\n");sleep(2);}return0;}7、共享內(nèi)存8、共享內(nèi)存使用的步驟(1)創(chuàng)建共享內(nèi)存塊的一個(gè)外鍵#include<sys/types.h>#include<sys/ipc.h>key_tftok(constchar*pathname,intproj_id);注意:pathname必須是系統(tǒng)中真實(shí)存在的而且穩(wěn)定的路徑,一般proj—id用一個(gè)ascii字符來代替獲取或者創(chuàng)建共享內(nèi)存塊#include<sys/ipc.h>#include<sys/shm.h>intshmget(key_tkey,size_tsize,intshmflg);注意:第一個(gè)參數(shù)一般為在步驟1所創(chuàng)建或獲取的外鍵,如果你的共享內(nèi)存塊是一個(gè)私有共享內(nèi)存塊,可以選擇為IPC_PRIVATE;第二個(gè)參數(shù)為所創(chuàng)建或獲取的共享內(nèi)存塊的大小(以字節(jié)為單位);第三個(gè)參數(shù)所為所創(chuàng)建或獲取共享內(nèi)存塊的權(quán)限:IPC_CREAT:當(dāng)用key所對應(yīng)共享內(nèi)存不存在時(shí)則創(chuàng)建它;IPC_EXCL:當(dāng)空享內(nèi)存塊存在則創(chuàng)建失??;0666:共享內(nèi)塊的權(quán)限;該函數(shù)的返回值,當(dāng)創(chuàng)建成功是為共享內(nèi)存塊的內(nèi)部標(biāo)識!(3)共享內(nèi)存塊的映射#include<sys/types.h>#include<sys/shm.h>void*shmat(intshmid,constvoid*shmaddr,intshmflg);把shmid所標(biāo)識的共享內(nèi)存塊映射調(diào)用進(jìn)程的地址空間,第2、3參數(shù)一般為0;當(dāng)映射成功是返回共享內(nèi)存塊在用戶空間地址,失敗則為-1;3)撤銷共享內(nèi)存塊的映射#include<sys/types.h>#include<sys/shm.h>intshmdt(constvoid*shmaddr);當(dāng)進(jìn)程不需要對共享內(nèi)存塊進(jìn)行讀寫的時(shí)候調(diào)用該函數(shù)4)刪除共享內(nèi)存塊#include<sys/ipc.h>#include<sys/shm.h>intshmctl(intshmid,intcmd,structshmid_ds*buf);一般的調(diào)用格式:shmctl(shmid,IPC_RMID,NULL);小任務(wù):進(jìn)程1把從鍵盤獲取的字符串通過共享內(nèi)存發(fā)送給進(jìn)程2,進(jìn)程接手后顯示出來,當(dāng)接收到”exit”時(shí)退出。需要通過信號處理進(jìn)程1、2的同步關(guān)系:當(dāng)進(jìn)程往共享內(nèi)寫字符串后給進(jìn)程2發(fā)送信號。提示:共享內(nèi)塊的數(shù)據(jù)定義:structshm_struct{intwriterProcessId;intreaderProcessId;charbuf[512];};參考代碼://shmWriter.c#include<sys/types.h>#include<sys/ipc.h>#include<stdio.h>#include<sys/shm.h>#include<sys/signal.h>#include<string.h>〃定義結(jié)構(gòu)體以格式化共享內(nèi)存塊,并聲明了該結(jié)構(gòu)體類型指針變量pShmstructshm_struct{intwriterProcessId;intreaderProcessId;charbuf[512];}*pShm;intmain(){intshmid;key_tkey=ftok("/home",'a');//獲取共享內(nèi)存塊外鍵printf("Key=%d\n",key);shmid=shmget(key,sizeof(structshm_struct),IPC_CREATI0666);〃獲取共享內(nèi)存塊標(biāo)示符if(shmid<0){perror("Failedtocreatesharememory!\n");return-1;}printf("shmid=%d\n",shmid);pShm=(structshm_struct*)shmat(shmid,O,O);〃映射共享內(nèi)存塊bzero(pShm,sizeof(structshm_struct));//把共享內(nèi)存塊清0pShm->writerProcessId=getpid();//初始化內(nèi)存塊的寫者pidwhile(1){fgets(pShm->buf,512,stdin);〃從鍵盤獲取字符串if(pShm->readerProcessId!=0){kill(pShm->readerProcessId,SIGUSR1);〃給讀者發(fā)信號表示已經(jīng)寫了一個(gè)新的字符串到共享內(nèi)存塊}}return0;}//shmReader.c#include<sys/types.h>#include<sys/ipc.h>#include<stdio.h>#include<sys/shm.h>#include<sys/signal.h>#include<string.h>structshm_struct{intwriterProcessId;intreaderProcessId;charbuf[512];}*pShm;intflag=0;voidcan_read_shm(intsig){flag=1;}intmain(){intshmid;key_tkey=ftok("/home",'a');printf("Key=%d\n",key);shmid=shmget(key,sizeof(structshm_struct),IPC_CREAT|0666);if(shmid<0){perror("Failedtocreatesharememory!\n");return-1;}printf("shmid=%d\n",shmid);pShm=(structshm_struct*)shmat(shmid,0,0);pShm->readerProcessId=getpid();signal(SIGUSR1,can_read_shm);while(1){if(flag==1){flag=0;printf("%s",pShm->buf);if(strncmp(pShm->buf,"exit",4)==0)break;}}pShm->readerProcessId=0;return0;}消息隊(duì)列相關(guān)函數(shù):msggetmsgsndmsgrcvmsgctl(1)消息緩沖區(qū)的最大長度(含消息類型)的最大長度不要超過4096字節(jié)(2) msgsndmsgrcv的正文長度參數(shù)是以字節(jié)為單位的;(3) 定義消息結(jié)構(gòu)體時(shí),消息類型一定最開始的成員:錯(cuò)誤的定義:structmessage_buf{charbuf[512];longmsgType;

};正確的定義:structmessage_buf{longmsgType;charbuf[512];};小任務(wù):基于消息隊(duì)列的通信方式實(shí)現(xiàn)一個(gè)服務(wù)器/客戶端模式的計(jì)算系統(tǒng)(1)服務(wù)端從消息隊(duì)列讀取需要計(jì)算的兩個(gè)整數(shù),求和后把結(jié)果同通過消息隊(duì)列返回客戶端;(2)客戶端從鍵盤讀取兩個(gè)整數(shù),通過消息隊(duì)列發(fā)送服務(wù)器,接收到計(jì)算結(jié)果后顯示出來(3)要求服務(wù)端能同時(shí)處理多個(gè)客戶端的請求分析:服務(wù)器端:(1)初始化;(2)從消息隊(duì)列獲取消息;(3)求和計(jì)算;(4)給客戶端發(fā)送和消息(5)轉(zhuǎn)(2)客戶端:(1)初始化;(2)從鍵盤獲取兩個(gè)整數(shù);(3)通過消息隊(duì)列發(fā)送兩個(gè)整數(shù)給服務(wù)器;(4)接收服務(wù)器端和消息;(5)轉(zhuǎn)(2)參考代碼://msgServer.c#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<unistd.h>#include"comm.h"(此頭文件包含結(jié)構(gòu)體structc2s_Message、structs2s_message)intmain(){intmsgid;intsum;structc2s_messagec2sMessage;structs2c_messages2cMessage;key_tkey=ftok("/usr/lib",'a')創(chuàng)建外鍵msgid=msgget(key,IPC_CREAT

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論