UNIX进程间通信课件_第1页
UNIX进程间通信课件_第2页
UNIX进程间通信课件_第3页
UNIX进程间通信课件_第4页
UNIX进程间通信课件_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

UNIX進程間通信第一節進程通信的基本概念進程通信包括控制資訊傳遞和大批量資訊傳遞.1.通信方式1)主從式-----通信進程間有主從之分。2)會話式-----用請求/服務方式完成通信。3)平等方式——通過消息緩衝或郵箱完成通信;或通過共用緩衝區通信。2.Unix中的進程通信基本通信:用於傳遞進程間的控制資訊;管道通信:將管道檔作為通信的介質,傳遞進程間的資訊;IPC(InterProcessCommuation)通信:用於進程間大量的數據傳送。第二節UNIX的基本進程通信鎖檔通信通信進程雙方在某個指定目錄中(通常會是/tmp目錄)查找是否有一個雙方約定好的鎖檔存在,存在時完成一種處理,不存在時完成另一種操作。記錄鎖定檔通信記錄檔中連續存儲的位元組組成的特定數據段或數據區。實現:使用UNIX中已有的一個加鎖程式。方式建議型鎖定強制型鎖定常用操作方法:系統調用fcntl及庫函數lockf3.信號通信信號進程中非同步發生事件的提示資訊。UNIX進程通信中可使用的信號已做了預先的內部約定。查看各信號的描述說明:man命令或在頭檔<sys/signal.h>中。信號的作用用於進程間的同步和互斥進程的條件執行信號的發送編程級的:系統調用kill(pid,sig)Shell命令級的:kill命令注:普通用戶只能向自己創建的進程發送信號;超戶可以向任意進程發送信號。信號的捕獲和處理系統調用signal(sig,func())功能:為sig信號註冊指定的處理函數func三種取值:SIG-IGN:忽略所接收信號SIG-DFL:恢復對信號的缺省處理函數名:自定義函數/*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;

signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){/*signal(SIGINT,SIG_IGN);*/

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}1)執行中不用delete或^c鍵打斷%test_signalsleepcall#1……sleepcall#4Exiting./*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}2)在第二次迴圈後按了delete鍵;%test_signalsleepcall#1sleepcall#2CATCHINT:signo=2;Return.sleepcall#3sleepcall#4Exiting./*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}3)第二次迴圈後按了delete鍵,第三次又按了delete鍵。%test_signalsleepcall#1sleepcall#2CATCHINT:signo=2;Return.sleepcall#3

signal(SIGINT,catchint());信號複位:信號處理函數僅用一次,處理過一次後恢復到默認處理程式狀態。第三節管道通信管道UNIX中的一種先進先出(FIFO)的特殊檔管道的讀寫依然使用read、write系統調用管道讀出寫入寫管道與寫檔的區別寫管道總在管道的末尾寫;寫檔可以通過調整檔指針在任意位置寫。寫管道每次寫入的位元組數受系統參數限制。設備忙時,write會被阻塞延遲執行。寫一個沒有以寫方式打開的管道,將生成SIGPIPE信號,error置為EPIPE。讀管道與讀檔的區別讀管道總從管道的當前位置讀;讀檔支持檔指針的移動。當管道中無資訊時read系統調用被阻塞;讀空文件返回空串。若管道未被其他進程以寫方式打開,就對管道進行read,返回0值。無名管道創建方法:Shell命令級的:|管道符編程級的:intfds[2];

intpipe(fds);使用fds[0]讀取管道中的數據;使用fds[1]往管道中寫入數據。應用場合:父子進程間通信示例/*用管道將數據從父進程傳遞到子進程*/#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sting.h>#defineBUFSIZ512main(intargc,char*argv[]){int

fds[2];staticcharmessage[BUFSIZ];if(argc!=2){

fprintf(stderr,”Usage:%smessage\n”,*argv);

exit(1);}if(pipe(fds)==-1){

perror(“pipe”);exit(2);}switch(fork()){case-1:perror(“forkerror.”);

exit(3);case0:close(fds[1]);

if(read(fds[0],message,BUFSIZ)!=-1){ printf(“Messagereceivedbychild:[%s]\n”,message); fflush(stdout); }else{perror(“Readerror”); exit(4); } break;default:

close(fds[0]);

if(write(fds[1],argv[1],strlen(argv[1]))!=-1){printf("Messagesentbyparent:[%s]\n",argv[1]);

fflush(stdout);

}else{

perror("write");

exit(5);}

}exit(0);}%a.out"messageisabc"Messagereceivedbychild:[messageisabc]Messagesentbyparent:[messageisabc]有名管道特點生成時在檔系統中生成一個目錄表項;允許兩個獨立的進程借此進行通信。創建方法:shell命令級的:mknod命令例:%mknodPFILEp管道檔案名表示生成一個管道檔創建方法(續)庫函數popen()

管道檔案名訪問許可權典型用法:……mknod(path,S_IFIFO|mode,0);……fd=open(path,0);……read(fd,buf,PIPE_BUF);……編程級的:系統調用mknod()第四節SystemVIPCSystemVIPC的三種通信機制消息佇列(messagequeue)進程間分類格式化的數據傳送。共用記憶體(sharedmemory)通過共用同一塊記憶體空間實現進程間通信。信號燈(semaphore)多個進程在一組信號燈上同步。相關知識IPC識別字每個SystemVIPC對象都有一個,對本類IPC對象唯一。key_t鍵三種類型的SystemVIPC使用key_t值作為它們的名字;<sys/types.h>把key_t定義為一個整數,通常由一個進程相關或用戶相關的唯一的字串通過ftok函數生成。內核中的消息佇列結構消息機制提供的系統調用msgget:返回消息描述符,用於創建或指定一消息佇列msgqid=msgget(key,msgflg)key_tkey;/*關鍵字*/intmsgflg;/*get的標誌及許可權*/msgsnd:發送消息,成功返回0,出錯為-1msgsnd(msgqid,msgp,msgsz,msgflg)intmsgqid;/*消息描述符*/structmsgbuf*msgp;

/*消息類型和字元數組的指針*/intmsgsz,msgflg;/*

msgsz是數組大小,msgflg是同步標識*/msgrcv:接受消息msgrcv(msgqid,msgp,msgsz,msgtype,msgflg)intmsgqid;structmsgbug*msgp;intmsgsz;longmsgtype;

/*用戶想要讀出消息的類型*/intmsgflg;msgctl:查詢、設置或刪除消息描述符的狀態msgctl(msgqid,cmd,buf)intmsgqid,cmd;/*cmd是規定命令的類型:IPC_STAT、IPC_SET或IPC_RMID*/msgqid_ds*buf;/*用戶數據結構的地址*/相關的頭檔:sys/types.h sys/ipc.h sys/msg.h相關管理命令ipcs命令ipcrm命令系統調用的使用關係和順序:首先用msgget建立或打開一個消息佇列,得到msgqid。例:msgqid=msgget(MSGKEY,0777)然後,用上述獲得的msgqid調用msgsnd和msgrcv發送和接受消息。或,調用msgctl

來設置或獲取消息佇列屬性、或刪除該消息佇列。例:客戶進程和服務進程用消息機制進行資訊通信/*msg-client.c*/#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#defineMSGKEY75structmsgform{longmtype;charmtext[256];};main(){structmsgformmsg;

intmsgqid,pid,*pint;

msgqid=msgget(MSGKEY,0777);pid=getpid();printf(“client:pid=%d\n”,pid);pint=(int*)msg.mtext;*pint=pid;msg.mtype=1;msgsnd(msgqid,&msg,sizeof(int),0);msgrcv(msgqid,&msg,256,pid,0);printf(“client:receivefrompid%d\n”,*pint);}/*msg-server.c*/#inclide<sys/types.h>#inclide<sys/ipc.h>#inclide<sys/msg.h>#defineMSGKEY75structmsgform{longmtype;charmtext[256];}msg;

intmsgqid;main(){inti,pid,*pint;externcleanup();for(i=0;i<23;i++)signal(i,cleanup);sgqid=msgget(MSGKEY,0777|IPC_CREAT);

printf(“server:pid=%d\n”,getpid());for(;;){

msgrcv(msgqid,&msg,256,1,0);pint=(int*)msg.mtext;pid=*pint;

printf(“server:receivefrompid%d\n”,pid);msg.mtype=pid;*pint=getpid();

sgsnd(msgqid,&msg,sizeof(int),0);

}}cleanup()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论