




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第5章SystemV進(jìn)程間通信12SystemV
IPC基礎(chǔ)
消息隊(duì)列
3信號量通信機(jī)制
4共享內(nèi)存
1為了提供與其他系統(tǒng)的兼容性,Linux也支持三種SystemV的進(jìn)程間通信機(jī)制:消息隊(duì)列、信號量和共享內(nèi)存,Linux對這些機(jī)制的實(shí)施大同小異。我們把信號量、消息隊(duì)列和共享內(nèi)存統(tǒng)稱SystemVIPC對象。就像每個(gè)文件都有一個(gè)打開文件號一樣,每個(gè)對象也都有唯一的識別號,進(jìn)程可以通過系統(tǒng)調(diào)用傳遞的識別號來存取這些對象。與文件的存取一樣,對這些對象的存取也要驗(yàn)證存取權(quán)限,SystemVIPC可以通過系統(tǒng)調(diào)用對對象的創(chuàng)建者設(shè)置這些對象的存取權(quán)限。2023/6/12ipcs命令I(lǐng)pcs命令用于顯示消息隊(duì)列、共享內(nèi)存、信號量的信息。
q顯示消息隊(duì)列s顯示信號量
m顯示共享內(nèi)存a詳細(xì)信息對每一個(gè)資源,這個(gè)命令會顯示:TYPE包括信息隊(duì)列(q),共享內(nèi)存(m),或者信號量(s)。ID資源條目的唯一的表示號KEY應(yīng)用程序存取資源使用的參數(shù)。MODE存取模式和許可權(quán)限的標(biāo)記OWNERandGROUP登錄名和用戶屬主的組號2023/6/13key值和ID值Linux系統(tǒng)為每個(gè)IPC機(jī)制都分配了唯一的ID,所有針對該IPC機(jī)制的操作都使用對應(yīng)的ID。因此,通信的雙方都需要通過某個(gè)辦法來獲取ID值。顯然,創(chuàng)建者根據(jù)創(chuàng)建函數(shù)的返回值可獲取該值,但另一個(gè)進(jìn)程如何實(shí)現(xiàn)呢?由于Linux兩個(gè)進(jìn)程不能隨意訪問對方的空間(一個(gè)特殊是,子進(jìn)程可以繼承父親進(jìn)程的數(shù)據(jù),實(shí)現(xiàn)父親進(jìn)程向子進(jìn)程的單向傳遞),也就不能夠直接獲取這一ID值。為解決這一問題,IPC在實(shí)現(xiàn)時(shí)約定使用key值做為參數(shù)創(chuàng)建,如果在創(chuàng)建時(shí)使用相同的key值將得到同一個(gè)IPC對象的ID(即一方創(chuàng)建,另一方獲取的是ID),這樣就保證了雙方可以獲取用于傳遞數(shù)據(jù)的IPC機(jī)制ID值。2023/6/14ftokexternkey_tftok(__constchar*__pathname,int__proj_id);此函數(shù)有兩個(gè)參數(shù),pathname為文件路徑名,可以是特殊文件(例如目錄文件),也可以是當(dāng)前目錄“.”,而通常也是設(shè)置此參數(shù)為當(dāng)前目錄,因?yàn)楫?dāng)前目錄一般都是存在的,且不會被立即刪除。第二個(gè)參數(shù)為一個(gè)int型變量。2023/6/15例:ftok的使用#include<stdio.h>#include<sys/types.h>main(){ key_tkey; key=ftok(".",1); printf("thekeyis%x\n",key); }2023/6/16ftokftok函數(shù)創(chuàng)建key值過程中使用了該文件屬性的st_dev和st_ino。具體構(gòu)成如下:key值的第31-24為ftok()第二個(gè)參數(shù)的低8位;key值的第23-16為該文件的st_dev屬性的低8位;key值的第15-0為該文件的st_ino屬性的低16位;因此,如果使用相同的文件路徑及整數(shù),得到的key值是唯一的,而唯一的key值創(chuàng)建某類IPC機(jī)制時(shí)將得到同一個(gè)IPC機(jī)制(但如果使用相同的key值分別創(chuàng)建一個(gè)消息隊(duì)列和一個(gè)信號量,兩者沒有聯(lián)系),而文件路徑的訪問對兩個(gè)進(jìn)程來說很容易統(tǒng)一,因此,便捷的實(shí)現(xiàn)了兩進(jìn)程通信機(jī)制的確定。2023/6/17例:ftok函數(shù)和參數(shù)的關(guān)系#include<sys/ipc.h>#include<stdio.h>#include<stdlib.h>#include<sys/stat.h>main(intargc,char*argv[]){ key_tkey; inti; structstatbuf; if(argc!=3) { printf("errorusage\n"); return1; } i=atoi(argv[2]);2023/6/18例:ftok函數(shù)和參數(shù)的關(guān)系 if((stat(argv[1],&buf))==-1) { perror("stat"); exit(EXIT_FAILURE); } printf("\n",buf.st_dev); printf("\n",buf.st_ino); printf("number=%x\n",i); key=ftok(argv[1],i); printf("key=0x%x",key);}2023/6/19第5章SystemV進(jìn)程間通信12SystemV
IPC基礎(chǔ)
消息隊(duì)列
3信號量通信機(jī)制
4共享內(nèi)存
10消息隊(duì)列的基本概念消息隊(duì)列就是一個(gè)消息的鏈表,是一系列保存在內(nèi)核中的消息的列表。用戶進(jìn)程可以向消息隊(duì)列添加消息,也可以從消息隊(duì)列讀取消息。消息隊(duì)列與管道通信相比,其優(yōu)勢是對每一個(gè)消息指定特定消息類型,接收的時(shí)候不需要按隊(duì)列次序,而是可以根據(jù)自定義條件接收特定類型的消息??梢园严⒖醋饕粋€(gè)記錄,具有特定的格式以及特定的優(yōu)先級。對消息隊(duì)列有寫權(quán)限的進(jìn)程可以向消息隊(duì)列中按照一定的規(guī)則添加新消息;對消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀取消息。2023/6/111消息隊(duì)列屬性2023/6/112消息structmsg結(jié)構(gòu)體//comefrom/usr/src/kernels/’uname–r’/inlcude/linux/msg.h/*onemsg_msgstructureforeachmessage*/structmsg_msg{ structlist_headm_list; longm_type; intm_ts;/*messagetestsize*/ structmsg_msgseg*next; void*security; /*theactualmessagefollowsimmediately*/};2023/6/113消息隊(duì)列2023/6/114對消息隊(duì)列的說明對消息隊(duì)列的限定://comefrom/usr/include/linux/msg.h#defineMSGMNI16/*<=IPCMNI*//*max#ofmsgqueueidentifiers*/#defineMSGMAX8192/*<=INT_MAX*//*maxsizeofmessage(bytes)*/#defineMSGMNB16384/*<=INT_MAX*//*defaultmaxsizeofamessagequeue*/不同的系統(tǒng)限制值可以通過msgctl函數(shù)使用IPC_INFO參數(shù)獲得。2023/6/115消息隊(duì)列常用的系統(tǒng)調(diào)用函數(shù)功能ftok根據(jù)文件路徑和參數(shù)生成標(biāo)準(zhǔn)keymsgget創(chuàng)建或打開消息隊(duì)列msgsnd添加消息msgrcv讀取消息msgctl控制消息隊(duì)列2023/6/116創(chuàng)建消息隊(duì)列externintmsgget(key_t__key,int__msgflg);第一個(gè)參數(shù)key為由ftok創(chuàng)建的key值。第二個(gè)參數(shù)__msgflg的低位用來確定消息隊(duì)列的訪問權(quán)限。如0770,為文件的訪問權(quán)限類型。此外,還可以附加以下參數(shù)值。這些值可以與基本權(quán)限以或的方式一起使用。//comefrom/usr/include/bit/ipc.h/*resourcegetrequestflags*/#defineIPC_CREAT00001000/*createifkeyisnonexistent*/#defineIPC_EXCL00002000/*failifkeyexists*/#defineIPC_NOWAIT00004000/returnerroronwait*/2023/6/117msgget返回說明:成功執(zhí)行時(shí),返回消息隊(duì)列標(biāo)識值。失敗返回-1,errno被設(shè)為以下的某個(gè)值,有時(shí)也會返回0,這個(gè)時(shí)候也是可以正常使用的。EACCES:指定的消息隊(duì)列已存在,但調(diào)用進(jìn)程沒有權(quán)限訪問它,而且不擁有CAP_IPC_OWNER權(quán)限EEXIST:key指定的消息隊(duì)列已存在,而msgflg中同時(shí)指定IPC_CREAT和IPC_EXCL標(biāo)志ENOENT:key指定的消息隊(duì)列不存在,同時(shí)msgflg中不指定IPC_CREAT標(biāo)志ENOMEM:需要建立消息隊(duì)列,但內(nèi)存不足ENOSPC:需要建立消息隊(duì)列,但已達(dá)到系統(tǒng)的最大消息隊(duì)列容量2023/6/118例:創(chuàng)建消息隊(duì)列#include<stdio.h>#include<sys/ipc.h>#include<sys/types.h>intmain(){ key_tkey; key=ftok(".",1); printf("thekeyis%x\n",key); intid; id=msgget(key+1,IPC_CREAT|0666); printf("id=%d\n",id); system(“ipcs”);}2023/6/119消息隊(duì)列屬性控制externintmsgctl(int__msqid,int__cmd,structmsqid_ds*__buf);第一個(gè)參數(shù)__msqid為消息隊(duì)列標(biāo)識符,該值為使用msgget函數(shù)創(chuàng)建消息隊(duì)列的返回值。第二個(gè)參數(shù)__cmd為執(zhí)行的控制命令,即要執(zhí)行的操作。包括以下選項(xiàng)://comefrom/usr/include/linux/ipc.h/*Controlcommandsusedwithsemctl,msgctlandshmctlseealsospecificcommandsinsem.h,msg.handshm.h*/#defineIPC_RMID0/*removeresource*/#defineIPC_SET1/*setipc_permoptions*/#defineIPC_STAT2/*getipc_permoptions*/#defineIPC_INFO3/*seeipcs*/2023/6/120例:刪除消息隊(duì)列#include<stdio.h>#include<sys/ipc.h>#include<sys/types.h>intmain(){ key_tkey; intid; key=ftok(".",1); id=msgget(key+1,IPC_CREAT|0666); printf("id=%d\n",id); msgctl(id,IPC_RMID,NULL); sytem(“ipcs”);}2023/6/121發(fā)送信息到消息隊(duì)列externintmsgsnd(int__msqid,__constvoid*__msgp,size_t__msgsz,int__msgflg)第一個(gè)參數(shù)msqid為指定的消息隊(duì)列標(biāo)識符(由msgget生成的消息隊(duì)列標(biāo)識符),即將消息添加到那個(gè)消息隊(duì)列中。第二個(gè)參數(shù)msgp為指向的用戶定義緩沖區(qū)。第三個(gè)參數(shù)為接收信息的大小,其數(shù)據(jù)類型為size_t,即unsignedint類型。其大小為0到系統(tǒng)對消息隊(duì)列的限定值。第四個(gè)參數(shù)用來指定在達(dá)到系統(tǒng)為消息隊(duì)列鎖定的界限(如達(dá)到字?jǐn)?shù)限制)時(shí)應(yīng)采取的操作。2023/6/122發(fā)送信息到消息隊(duì)列(2)
第二個(gè)參數(shù)其定義如下://comefrom/usr/include/linux/msg.h/*messagebufferformsgsndandmsgrevcalls*/structmsgbuf{longmtype;/*typeofmessage*/charmtext[1];/*messagetext*/}mtype是一個(gè)正整數(shù),由產(chǎn)生消息的進(jìn)程生成,用于表示消息的類型,因此,接收進(jìn)程可以用來進(jìn)行消息選擇(消息隊(duì)列在存儲信息時(shí)是按發(fā)送的先后順序放置的)。mtext是文本內(nèi)容,即消息內(nèi)容,此處大小為1,顯然不夠用,在使用時(shí)自己重新定義此結(jié)構(gòu)。2023/6/123發(fā)送信息到消息隊(duì)列(3)第四個(gè)參數(shù)用來指定在達(dá)到系統(tǒng)為消息隊(duì)列鎖定的界限(如達(dá)到字?jǐn)?shù)限制)時(shí)應(yīng)采取的操作。:如果設(shè)置為IPC_NOWAIT,如果需要等待,則不發(fā)送消息并且調(diào)用進(jìn)程立即返回錯誤信息EAGAIN.如果設(shè)置為0,則忽略標(biāo)志位。成功調(diào)用后,此函數(shù)將返回0,否則返回-1,同時(shí)將對消息隊(duì)列msqid數(shù)據(jù)結(jié)構(gòu)的成員執(zhí)行下列操作:msg_qnum以1為增量遞增。msg_lspid設(shè)置為調(diào)用進(jìn)程的進(jìn)程ID。msg_stime設(shè)置為當(dāng)前時(shí)間。2023/6/124從消息隊(duì)列接收信息externintmsgrev(int__msqid,void*__msgp,size_t__msgsz,longint__msgtyp,int__msgflg);此函數(shù)從與msqid指定的消息隊(duì)列標(biāo)識符相關(guān)聯(lián)的隊(duì)列中讀取消息,并將其放置到msgp指向的結(jié)構(gòu)中。第一個(gè)參數(shù)為讀的對象,即從哪個(gè)消息隊(duì)列獲得消息。第二個(gè)參數(shù)為一個(gè)臨時(shí)消息數(shù)據(jù)結(jié)構(gòu),用來保存讀取的信息。其定義與發(fā)送信息的第二個(gè)參數(shù)相同。第三個(gè)參數(shù)msgsz指定mtext的大?。ㄒ宰止?jié)為單位)。如果收到的消息大于msgsz,并且msgflg&MSG_NOERROR為真,則將該消息截至msgsz字節(jié),消息的截?cái)嗖糠謱G失,并且不向調(diào)用進(jìn)程提供截?cái)嗟奶崾?023/6/125從消息隊(duì)列接收信息(2)
第四個(gè)參數(shù)msgtyp指定請求的消息類型:msgtyp=0收到隊(duì)列中的第一條消息,任意類型。msgtyp>0收到第一條msgtyp類型的消息。msgtyp<0收到第一條最低類型(小于或等于msgtyp的絕對值)的消息。第五個(gè)參數(shù)msgflg指定所需類型消息不在隊(duì)列上時(shí)將要采取的操作。0,表示忽略;IPC_NOWAIT,如果消息隊(duì)列為空,則返回一個(gè)ENOMSG,并將控制權(quán)交回調(diào)用函數(shù)的進(jìn)程。2023/6/126消息隊(duì)列應(yīng)用實(shí)例#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/msg.h>#include<sys/ipc.h>#include<unistd.h>structmsgmbuf{ longmsg_type; charmsg_text[512];};2023/6/127消息隊(duì)列應(yīng)用實(shí)例intmain(){ intqid; key_tkey; intlen; structmsgmbufmsg; if((key=ftok(".",'a'))==-1) { perror("ftok"); exit(EXIT_FAILURE); } if((qid=msgget(key,IPC_CREAT|0666))==-1) { perror("msgget"); exit(EXIT_FAILURE); }2023/6/128消息隊(duì)列應(yīng)用實(shí)例 printf("IDofthequeueis:%d\n",qid); puts("pleaseinputthemssage:"); if((fgets((&msg)->msg_text,512,stdin))==NULL) { puts("nomessage!"); exit(EXIT_FAILURE); } msg.msg_type=getpid(); len=strlen(msg.msg_text); if((msgsnd(qid,&msg,len,0))<0) { perror("msgsnd"); exit(EXIT_FAILURE); }
2023/6/129消息隊(duì)列應(yīng)用實(shí)例 if((msgrcv(qid,&msg,512,0,0))<0) { perror("msgrcv"); exit(EXIT_FAILURE); } printf("themessageis:%s\n",(&msg)->msg_text); if((msgctl(qid,IPC_RMID,NULL))<0) { perror("msgctl"); exit(EXIT_FAILURE); } exit(0);}2023/6/130第5章SystemV進(jìn)程間通信12SystemV
IPC基礎(chǔ)
消息隊(duì)列
3信號量通信機(jī)制
4共享內(nèi)存
31信號量基本概念信號量是操作系統(tǒng)中解決進(jìn)程或線程同步與互斥的最重要機(jī)制之一。Linux內(nèi)核提供SystemV的信號量機(jī)制,用于實(shí)現(xiàn)進(jìn)程之間通信。信號量常用系統(tǒng)調(diào)用見下表函數(shù)功能sem_init初始化一個(gè)信號量sem_wait阻塞線程sem_post增加信號量的值sem_destory釋放信號量2023/6/132信號量集合屬性2023/6/133信號量結(jié)構(gòu)//comefrom/usr/src/kernels/’uname-r’/include/linux/sem.h/*Onesemaphorestructureforeachsemaphoreinthesystem.*/structsem{ intsemval;/*currentvalue*/ intsempid;/*pidoflastoperation*/};2023/6/134信號量通信機(jī)制概念圖2023/6/135創(chuàng)建信號量集合externintsemget(key_t__key,int__nsems,int__semflg);第一個(gè)參數(shù)為key_t類型的key值,一般由ftok函數(shù)產(chǎn)生。第二個(gè)參數(shù)__nsems為創(chuàng)建的信號量個(gè)數(shù),各信號量以數(shù)組的方式存儲。這個(gè)數(shù)組用于初始化數(shù)組對象。第三個(gè)參數(shù)__semflg用來標(biāo)識信號量集合的權(quán)限。如0770,為文件的訪問權(quán)限類型。此外,還可以附加以下參數(shù)值。這些值可以與基本權(quán)限以或的方式一起使用。//comefrom/usr/include/bit/ipc.h/*resourcegetrequestflags*/#defineIPC_CREAT00001000/*createifkeyisnonexistent*/#defineIPC_EXCL00002000/*failifkeyexists*/#defineIPC_NOWAIT00004000/*returnerroronwait*/2023/6/136控制信號量集合、信號量externintsemctl(int__semid,int__semnum,int__cmd,……)該函數(shù)最多可有四個(gè)參數(shù)(有可能只有三個(gè)參數(shù))。第一個(gè)參數(shù)__semid為要操作的信號量集合標(biāo)識符,該值一般由semget函數(shù)返回。第二個(gè)參數(shù)為集合中信號量的編號。如果標(biāo)識某個(gè)信號量,此值為該信號量的下標(biāo)(從0到n-1);如果標(biāo)識整個(gè)信號量集合,則設(shè)置為0。第三個(gè)參數(shù)為要執(zhí)行的操作,如果是對整個(gè)信號量集合,這些操作在/usr/include/linux/ipc.h文件中定義。其操作包括IPC_RMID、IPC_SET、IPC_STAT和IPC_INFO,具體含義同msgctl的相關(guān)操作。2023/6/1372023/6/138信號量操作externintsemop(int__semid,structsembuf*__sops,size_t__nsops);此函數(shù)第一個(gè)參數(shù)為要操作的信號量集合標(biāo)識符,該值一般由semget函數(shù)返回。第二個(gè)參數(shù)為structsembuf結(jié)構(gòu)的變量,其定義如下://comefrom/usr/include/linux/sem.h/*semopsystemcallstakesanarrayofthese.*/structsembuf{unsignedshortsem_num;/*semaphoreindexinarray*/shortsem_op;/*semaphoreoperation*/shortsem_flg;/*operationflags*/}2023/6/139信號量操作(2)
此結(jié)構(gòu)體有三個(gè)成員變量。1)sem_num為操作的信號量編號。2)sem_op為作用于信號量的操作:該值如果為正整數(shù)表示增加信號量的值,如果為負(fù)整數(shù)表示減小信號量的值,如果為0表示對信號量的當(dāng)前值進(jìn)行是否為0的測試。3)sem_flg為操作標(biāo)識。2023/6/140使用信號量實(shí)現(xiàn)生產(chǎn)消費(fèi)問題生產(chǎn)消費(fèi)問題是一個(gè)經(jīng)典的數(shù)學(xué)問題,要求生產(chǎn)者-消費(fèi)者在固定的倉庫空間條件下,生產(chǎn)者每生產(chǎn)一個(gè)產(chǎn)品將占用一個(gè)倉庫空間,生產(chǎn)者生產(chǎn)的產(chǎn)品庫存不能越過倉庫的存儲量,消費(fèi)者每消費(fèi)一個(gè)產(chǎn)品將增加一個(gè)倉庫空間,消費(fèi)者在倉庫產(chǎn)品為0時(shí)不能再消費(fèi)。本例中采用信號量來解決這個(gè)問題,為了便于理解,本例中使用了兩個(gè)信號量,一個(gè)用來管理消費(fèi)者(以下為sem_produce),一個(gè)用來管理生產(chǎn)者(以下為sem_custom),即sem_produce表示當(dāng)前倉庫可用空間的數(shù)量,sem_custom用來表示當(dāng)前倉庫中產(chǎn)品的數(shù)量。對于生產(chǎn)者來說,其需要申請的資源為倉庫中的剩余空間,因此,生產(chǎn)者在生產(chǎn)一個(gè)產(chǎn)品前,申請sem_produce信號量,當(dāng)此信號量的值大于0,即有可用空間,將生產(chǎn)產(chǎn)品,并將sem_produce的值減去1(因?yàn)檎加昧艘粋€(gè)空間);同時(shí),當(dāng)其生產(chǎn)一個(gè)產(chǎn)品后,當(dāng)前倉庫的產(chǎn)品數(shù)量增加1,需要將sem_custom信號量自動加1。對于消費(fèi)者來說,其需要申請的資源為倉庫中的產(chǎn)品,因此,消費(fèi)者在消費(fèi)一個(gè)產(chǎn)品前,將申請sem_custom信號量,當(dāng)此信號量的值大于0時(shí),即有可用產(chǎn)品,將消費(fèi)一個(gè)產(chǎn)品,并將sem_custom信號量的值減去(因?yàn)橄M(fèi)了一個(gè)產(chǎn)品),同時(shí),當(dāng)消費(fèi)一個(gè)產(chǎn)品,當(dāng)前倉庫的剩余空間增加1,需要將sem_produce信號量自動加1。2023/6/141第5章SystemV進(jìn)程間通信12SystemV
IPC基礎(chǔ)
消息隊(duì)列
3信號量通信機(jī)制
4共享內(nèi)存
42共享內(nèi)存的基本概念共享內(nèi)存允許兩個(gè)或多個(gè)進(jìn)程共享一個(gè)給定的存儲區(qū),這一段存儲區(qū)可以被兩個(gè)或兩個(gè)以上的進(jìn)程映射至自身的地址空間中,數(shù)據(jù)不需要在進(jìn)程間復(fù)制,所以這是最快的一種IPC。使用共享內(nèi)存時(shí),多個(gè)進(jìn)程之間對一給定的存儲區(qū)需進(jìn)行同步訪問。即若一個(gè)進(jìn)程正在將數(shù)據(jù)放入共享存儲區(qū),則在它做完這一操作之前,其他進(jìn)程不應(yīng)當(dāng)去讀取這些數(shù)據(jù)。通常,信號量被用來實(shí)現(xiàn)對共享存儲的訪問。2023/6/143共享內(nèi)存屬性2023/6/144共享內(nèi)存IPC原理2023/6/145共享內(nèi)存與管道對比2023/6/146共享內(nèi)存的常用函數(shù)函數(shù)功能mmap建立共享內(nèi)存映射munmap解除共享內(nèi)存映射shmget獲取共享內(nèi)存區(qū)域的IDshmctl共享內(nèi)存控制shmat映射共享內(nèi)存對象shmdt分離共享內(nèi)存對象2023/6/147內(nèi)存映射函數(shù)mmap將某個(gè)文件的指定內(nèi)容映射到內(nèi)存空間中,該函數(shù)聲明如下:#include<sys/mman.h>void*mmap(void*start,size_tlength,intprot,intflags,intfd,off_toffset);此函數(shù)將在進(jìn)程的虛擬地址空間(起始為start,長度為length字節(jié))和與文件描述符fd關(guān)聯(lián)的文件(偏移量為offset,長度為length)之間建立映射。參數(shù)start一般情況下設(shè)置為NULL,由系統(tǒng)分配。第三個(gè)參數(shù)prot描述映射的內(nèi)存權(quán)限,該參數(shù)是以下選項(xiàng)的組合:PORT_READ允許讀該內(nèi)存PORT_WRITE允許寫該內(nèi)存PORT_EXEC允許執(zhí)行該內(nèi)存段PORT_NONE該內(nèi)存段不能被訪問2023/6/148內(nèi)存映射參數(shù)flags控制程序?qū)υ搩?nèi)存段的改變所造成的影響,常用選項(xiàng)如下:MAP_PRIVATE:內(nèi)存段是私有的,對他的修改只在此局部范圍內(nèi)有效,其他進(jìn)程不可見。MAP_SHARED:共享映射,某進(jìn)程對該段內(nèi)存空間的更新對其他進(jìn)程來說是可見的,但該文件的內(nèi)容并不會立即更新,要更新文件內(nèi)容,需要調(diào)用msync和munmap函數(shù)。2023/6/149例:內(nèi)存映射的使用#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/mman.h>typedefstruct{ charname[4]; intage;}people;main(intargc,char*argv[]){ pid_tresult; inti; people*p_map; chartemp;2023/6/150例:內(nèi)存映射的使用 p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); result=fork(); if(result<0) { perror("fork"); exit(EXIT_FAILURE); } elseif(result==0) { sleep(2); for(i=0;i<5;i++) printf("readbychild:No.%d'sageis:%d\n",i+1,(*(p_map+i)).age);2023/6/151例:內(nèi)存映射的使用 (*p_map).age=110; munmap(p_map,sizeof(people)*10); exit(0); } else { temp='a'; for(i=0;i<5;i++) { temp+=1; memcpy((p_map+i)->name,&temp,2); ((p_map+i)->age=20+i); }2023/6/152例:內(nèi)存映射的使用 sleep(5); printf("readbyparent:thesumofageis:%d\n",(*p_map).age); printf("unmaping>>>>\n"); munmap(p_map,sizeof(people)*10); printf("unmapsuccessful!\n"); }}2023/6/153創(chuàng)建共享內(nèi)存externintshmget(key_t__key,size_t__size,int__shmflg);第一個(gè)參數(shù)為key_t類型的key值,一般由ftok函數(shù)產(chǎn)生。第二個(gè)參數(shù)size為欲創(chuàng)建的共享內(nèi)存段大?。▎挝粸樽止?jié))。第三個(gè)參數(shù)shmflg用來標(biāo)識共享內(nèi)存段的創(chuàng)建標(biāo)識。包括//comefrom/usr/include/linu/ipc.h#defineIPC_CREAT01000/*Createkeyifkeydoesnotexist.*/#defineIPC_EXCL020000/*Failifkeyexists.*/#defineIPC_NOWAIT04000/*Returnerroronwait.*/2023/6/154創(chuàng)建共享內(nèi)存另外,在/usr/include/linux/shm.h文件還定義了另外兩個(gè)選項(xiàng)://comefrom/usr/include/linux/shm.h/*permissionflagforshmget*/#defineSHM_R0400/*orS_IRUGOfrom<linux/stat.h>*/#defineSHM_W0200/*orS_IWUGOfrom<linux/stat.h>*/2023/6/155共享內(nèi)存控制externintshmctl(int__shmid,int__cmd,structshmid_ds*__buf);第一個(gè)參數(shù)為要操作的共享內(nèi)存標(biāo)識符,該值一般由shmget函數(shù)返回。第二個(gè)參數(shù)為要執(zhí)行的操作,這些操作在/usr/include/linux/ipc.h文件中定義。其操作包括IPC_RMID、IPC_SET、IPC_STAT和IPC_INFO,具體含義同msgctl的相關(guān)操作。如果是超級用戶,還可以執(zhí)行以下兩個(gè)命令://comefrom/usr/include/sys/shm.h/*superusershmctlcommands*/#defineSHM_LOCK11#defineSHM_UNLOCK12第三個(gè)參數(shù)為structshmid_ds結(jié)構(gòu)的臨時(shí)共享內(nèi)存變量信息,此內(nèi)容根據(jù)第二個(gè)參數(shù)的不一樣而改變。2023/6/156映射共享內(nèi)存對象進(jìn)程使用共享內(nèi)存前,需要將該共享內(nèi)存與當(dāng)前進(jìn)程建立聯(lián)系,即將該共享內(nèi)存使用shmat函數(shù)映射到當(dāng)前進(jìn)程。其函數(shù)聲明如下:#include<sys/shm.h>externvoid*shmat(int__shmid,__constvoid*__shmaddr,int__shmflag);如果執(zhí)行成功,將返回共享內(nèi)存段首地址。第一個(gè)參數(shù)__shmid為要操作的共享內(nèi)存標(biāo)識符,該值一般由shmget函數(shù)返回。第二個(gè)參數(shù)shmaddr指定共享內(nèi)存的映射地址。如果該值為非零,則將用此值作為映射共享內(nèi)存的地址,如果此值為0,則由系統(tǒng)來選擇映射的地址。一般都將此值設(shè)置為0。2023/6/157映射共享內(nèi)存對象#include<sys/shm.h>externvoid*shmat(int__shmid,__constvoid*__shmaddr,int__shmflag);第三個(gè)參數(shù)用來指定共享內(nèi)存短的訪問權(quán)限和映射條件。//comefrom/usr/include/linux/shm.h/*modeforattach*/#defineSHM_RDNOLY010000/*read-onlyaccess*/#defineSHM_RND020000/*roundattachattachaddresstoSHMLBAbounary*/#defineSHM_REMAP040000/*take-overregiononattach*/#defineSHM_EXEC0100000/*executionaccess*/2023/6/158分離共享內(nèi)存對象在共享內(nèi)存使用完畢后,需要使用shmdt函數(shù)將其與當(dāng)前進(jìn)程分離。其函數(shù)聲明如下://comefrom/usr/include/sys/shm.hexternintshmdt(__constvoid*__shmaddr);其參數(shù)即為與當(dāng)前進(jìn)程分離的共享內(nèi)存標(biāo)志ID。2023/6/159例一#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/ipc.h>#include<sys/shm.h>#include<sys/types.h>typedefstruct{ charname[4]; intage;}people;main(){ intshm_id,i; key_tkey; people*p_map; char*name="/dev/shm/myshm2";2023/6/160例一 key=ftok(name,0); shm_id=shmget(key,4096,IPC_CREAT); if(shm_id==-1) { perror("shmget"); exit(EXIT_FAILURE); } p_map=(people*)shmat(shm_id,NULL,0); for(i=0;i<10;i++) { printf("name:%s\t",(p_map+i)->name); printf("age:%d\n",(p_map+i)->age); } if(shmdt(p_map)==-1) perror("shmdt");}2023/6/161例一#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/ipc.h>#include<sys/shm.h>#include<sys/types.h>typedefstruct{ charname[4]; intage;}people;main(){ intshm_id,i; key_tkey; people*p_map; char*name="/dev/shm/myshm2";2023/6/162例一 key=ftok(name,0); if(key==-1) { perror("ftok"); exit(EXIT_FAILURE); } shm_id=shmget(key,4096,IPC_CREAT|0666); if(shm_id==-1) { perror("shmget"); exit(EXIT_FAILURE); } p_map=shmat(shm_id,0,0);//(people*)shmat(shm_id,0,0); temp='a'; for(i=0;i<10;i++) { temp+=1; memcpy((p_map+i)->name,&temp,1); (p_map+i)->age=20+i; } if(shmdt(p_map)==-1) perror("shmdt");}2023/6/163例二#include<stdio.h>#include<stdlib.h>#include<sys/ipc.h>#include<sys/shm.h>#include<sys/types.h>#include<time.h>#include<unistd.h>typedefstruct{ charstr1[50]; charstr2[50]; intno1,no2;}str;2023/6/164例二main(intargc,char*agv[]){ intshm_id,i; key_tkey; str*p_map; time_ttimep; structtm*p; char*name="/dev/shm/myshm2"; key=ftok(name,0); shm_id=shmget(key,4096,IPC_CREAT|0666); if(shm_id==-1) { perror("shmget"); exit(EXIT_FAIL
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東省陽江市高新區(qū)2024-2025學(xué)年高一上學(xué)期1月期末地理試題 含解析
- 家電行業(yè)智能家電互聯(lián)互通方案
- 企業(yè)采購原材料采購協(xié)議
- 水電站建設(shè)運(yùn)營合作協(xié)議
- 旅游行業(yè)服務(wù)質(zhì)量保障協(xié)議
- 網(wǎng)絡(luò)科技行業(yè)數(shù)據(jù)安全使用承諾書
- 企業(yè)員工福利計(jì)劃與服務(wù)支持方案
- 私人教練健身訓(xùn)練合同協(xié)議
- 產(chǎn)品銷售代理合同集
- 汽車維修與故障診斷技術(shù)知識點(diǎn)總結(jié)題集
- 2024浙江寧波朗辰新能源有限公司招聘3人筆試參考題庫附帶答案詳解
- 2025年四川省高職單招計(jì)算機(jī)類職業(yè)技能測試題庫(供參考)
- 2024年01月舟山普陀農(nóng)村商業(yè)銀行2024年春季招考信息筆試歷年參考題庫附帶答案詳解
- 2025年常州機(jī)電職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 健康科普知識
- 2025-2030年中國真空凍干蔬菜市場發(fā)展走勢及投資策略分析報(bào)告
- 中央2025年交通運(yùn)輸部所屬事業(yè)單位招聘261人筆試歷年參考題庫附帶答案詳解
- 云南省昆明市2025年中考語文模擬試卷六套【附參考答案】
- 中智集團(tuán)所屬中智國際商務(wù)發(fā)展限公司招聘高頻重點(diǎn)提升(共500題)附帶答案詳解
- 【9語一模】2024年蚌埠市懷遠(yuǎn)縣中考一模語文試題
- 《芮城花椒栽培技術(shù)規(guī)程》
評論
0/150
提交評論