




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第5章System V進(jìn)程間通信 System VIPC基礎(chǔ)基礎(chǔ) 消息隊(duì)列消息隊(duì)列 信號(hào)量通信機(jī)制信號(hào)量通信機(jī)制 共享內(nèi)存共享內(nèi)存 為了提供與其他系統(tǒng)的兼容性,Linux也支持三種System V的進(jìn)程間通信機(jī)制:消息隊(duì)列、信號(hào)量和共享內(nèi)存消息隊(duì)列、信號(hào)量和共享內(nèi)存,Linux對(duì)這些機(jī)制的實(shí)施大同小異。我們把信號(hào)量、消息隊(duì)列和共享內(nèi)存統(tǒng)稱(chēng)System V IPC對(duì)象。就像每個(gè)文件都有一個(gè)打開(kāi)文件號(hào)一樣,每個(gè)對(duì)象也都有唯一的識(shí)別號(hào),進(jìn)程可以通過(guò)系統(tǒng)調(diào)用傳遞的識(shí)別號(hào)來(lái)存取這些對(duì)象。與文件的存取一樣,對(duì)這些對(duì)象的存取也要驗(yàn)證存取權(quán)限,System V IPC可以通過(guò)系統(tǒng)調(diào)用對(duì)對(duì)象的創(chuàng)建者設(shè)置這些對(duì)象
2、的存取權(quán)限。2021-12-82 ipcs 命令I(lǐng)pcs命令用于顯示消息隊(duì)列、共享內(nèi)存、信號(hào)量的信息。q 顯示消息隊(duì)列 s 顯示信號(hào)量m 顯示共享內(nèi)存 a 詳細(xì)信息對(duì)每一個(gè)資源,這個(gè)命令會(huì)顯示:TYPE 包括信息隊(duì)列(q),共享內(nèi)存(m),或者信號(hào)量(s)。ID 資源條目的唯一的表示號(hào)KEY應(yīng)用程序存取資源使用的參數(shù)。MODE 存取模式和許可權(quán)限的標(biāo)記OWNER and GROUP 登錄名和用戶(hù)屬主的組號(hào)2021-12-83key值和ID值 Linux系統(tǒng)為每個(gè)IPC機(jī)制都分配了唯一的ID,所有針對(duì)該IPC機(jī)制的操作都使用對(duì)應(yīng)的ID。因此,通信的雙方都需要通過(guò)某個(gè)辦法來(lái)獲取ID值。顯然,創(chuàng)建者
3、根據(jù)創(chuàng)建函數(shù)的返回值可獲取該值,但另一個(gè)進(jìn)程如何實(shí)現(xiàn)呢?由于Linux兩個(gè)進(jìn)程不能隨意訪問(wèn)對(duì)方的空間(一個(gè)特殊是,子進(jìn)程可以繼承父親進(jìn)程的數(shù)據(jù),實(shí)現(xiàn)父親進(jìn)程向子進(jìn)程的單向傳遞),也就不能夠直接獲取這一ID值。為解決這一問(wèn)題,IPC在實(shí)現(xiàn)時(shí)約定使用key值做為參數(shù)創(chuàng)建,如果在創(chuàng)建時(shí)使用相同的key值將得到同一個(gè)IPC對(duì)象的ID(即一方創(chuàng)建,另一方獲取的是ID),這樣就保證了雙方可以獲取用于傳遞數(shù)據(jù)的IPC機(jī)制ID值。 2021-12-84 ftok extern key_t ftok(_const char * _pathname, int _proj_id);此函數(shù)有兩個(gè)參數(shù),pathname
4、為文件路徑名,可以是特殊文件(例如目錄文件),也可以是當(dāng)前目錄“.”,而通常也是設(shè)置此參數(shù)為當(dāng)前目錄,因?yàn)楫?dāng)前目錄一般都是存在的,且不會(huì)被立即刪除。第二個(gè)參數(shù)為一個(gè)int型變量。2021-12-85例:ftok的使用#include #include main()key_t key;key=ftok(.,1);printf(the key is %xn,key);2021-12-8人民郵電出版社出版楊宗德編著6 ftok ftok函數(shù)創(chuàng)建key值過(guò)程中使用了該文件屬性的st_dev和st_ino。具體構(gòu)成如下:key值的第31-24為ftok()第二個(gè)參數(shù)的低8位;key值的第23-16為該文
5、件的st_dev屬性的低8位;key值的第15-0為該文件的st_ino屬性的低16位;因此,如果使用相同的文件路徑及整數(shù),得到的key值是唯一的,而唯一的key值創(chuàng)建某類(lèi)IPC機(jī)制時(shí)將得到同一個(gè)IPC機(jī)制(但如果使用相同的key值分別創(chuàng)建一個(gè)消息隊(duì)列和一個(gè)信號(hào)量,兩者沒(méi)有聯(lián)系),而文件路徑的訪問(wèn)對(duì)兩個(gè)進(jìn)程來(lái)說(shuō)很容易統(tǒng)一,因此,便捷的實(shí)現(xiàn)了兩進(jìn)程通信機(jī)制的確定。2021-12-87例:ftok函數(shù)和參數(shù)的關(guān)系#include #include #include #include main(int argc, char * argv)key_t key;int i;struct stat buf
6、;if(argc!=3)printf(error usagen);return 1;i=atoi(argv2);2021-12-88例:ftok函數(shù)和參數(shù)的關(guān)系if(stat(argv1,&buf)=-1) perror(stat);exit(EXIT_FAILURE);printf(file st_dev=%xn,buf.st_dev);printf(file st_ino=%xn,buf.st_ino);printf(number=%xn,i);key=ftok(argv1,i);printf(key=0 x%x ,key);2021-12-89第5章System V進(jìn)程間通信 S
7、ystem VIPC基礎(chǔ)基礎(chǔ) 消息隊(duì)列消息隊(duì)列 信號(hào)量通信機(jī)制信號(hào)量通信機(jī)制 共享內(nèi)存共享內(nèi)存 消息隊(duì)列的基本概念消息隊(duì)列就是一個(gè)消息的鏈表,是一系列保存在內(nèi)核中的消息的列表。用戶(hù)進(jìn)程可以向消息隊(duì)列添加消息,也可以從消息隊(duì)列讀取消息。消息隊(duì)列與管道通信相比,其優(yōu)勢(shì)是對(duì)每一個(gè)消息指定特定消息類(lèi)型,接收的時(shí)候不需要按隊(duì)列次序,而是可以根據(jù)自定義條件接收特定類(lèi)型的消息。可以把消息看作一個(gè)記錄,具有特定的格式以及特定的優(yōu)先級(jí)。對(duì)消息隊(duì)列有寫(xiě)權(quán)限的進(jìn)程可以向消息隊(duì)列中按照一定的規(guī)則添加新消息;對(duì)消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀取消息。2021-12-811消息隊(duì)列屬性2021-12-812消息
8、struct msg結(jié)構(gòu)體 /come from /usr/src/kernels/uname r/inlcude/linux/msg.h/*one msg_msg structure for each message */struct msg_msgstruct list_head m_list;long m_type;int m_ts; /*message test size */struct msg_msgseg* next;void * security;/* the actual message follows immediately */;2021-12-813消息隊(duì)列2021-1
9、2-814對(duì)消息隊(duì)列的說(shuō)明對(duì)消息隊(duì)列的限定:/come from /usr/include/linux/msg.h#define MSGMNI 16 /*=IPCMNI */ /* max # of msg queue identifiers */#define MSGMAX 8192 /*=INT_MAX */ /* max size of message (bytes) */#define MSGMNB 16384 /*=INT_MAX */ /*default max size of a message queue */不同的系統(tǒng)限制值可以通過(guò)msgctl函數(shù)使用IPC_INFO參數(shù)獲得
10、。2021-12-815消息隊(duì)列常用的系統(tǒng)調(diào)用函數(shù)函數(shù)功能功能ftok根據(jù)文件路徑和參數(shù)生成標(biāo)準(zhǔn)keymsgget創(chuàng)建或打開(kāi)消息隊(duì)列msgsnd添加消息msgrcv讀取消息msgctl控制消息隊(duì)列2021-12-816創(chuàng)建消息隊(duì)列 extern int msgget(key_t _key,int _msgflg);第一個(gè)參數(shù)key為由ftok創(chuàng)建的key值。第二個(gè)參數(shù)_msgflg的低位用來(lái)確定消息隊(duì)列的訪問(wèn)權(quán)限。如0770,為文件的訪問(wèn)權(quán)限類(lèi)型。此外,還可以附加以下參數(shù)值。這些值可以與基本權(quán)限以或的方式一起使用。/come from /usr/include/bit/ipc.h/*resou
11、rce get request flags */#define IPC_CREAT 00001000 /*create if key is nonexistent*/#define IPC_EXCL 00002000 /*fail if key exists */#define IPC_NOWAIT 00004000 /return error on wait */2021-12-817msgget返回說(shuō)明:成功執(zhí)行時(shí),返回消息隊(duì)列標(biāo)識(shí)值。失敗返回-1,errno被設(shè)為以下的某個(gè)值 ,有時(shí)也會(huì)返回0,這個(gè)時(shí)候也是可以正常使用的。EACCES:指定的消息隊(duì)列已存在,但調(diào)用進(jìn)程沒(méi)有權(quán)限訪問(wèn)它,而且
12、不擁有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ì)列容量2021-12-818例:創(chuàng)建消息隊(duì)列#include #include #include int main()key_t key;key=ftok(.,1);printf(the key is %xn,key);int id;id=msgget(key+1,IPC
13、_CREAT|0666);printf(id=%dn,id);system(“ipcs”);2021-12-8人民郵電出版社出版楊宗德編著19消息隊(duì)列屬性控制 extern int msgctl(int _msqid, int _cmd, struct msqid_ds *_ buf);第一個(gè)參數(shù)_msqid為消息隊(duì)列標(biāo)識(shí)符,該值為使用msgget函數(shù)創(chuàng)建消息隊(duì)列的返回值。第二個(gè)參數(shù)_cmd為執(zhí)行的控制命令,即要執(zhí)行的操作。包括以下選項(xiàng):/come from /usr/include/linux/ipc.h/*Control commands used with semctl, msgctl
14、and shmctl see also specific commands in sem.h, msg.h and shm.h */#define IPC_RMID 0 /*remove resource*/#define IPC_SET 1 /*set ipc_perm options */#define IPC_STAT 2 /*get ipc_perm options */#define IPC_INFO 3 /*see ipcs */2021-12-820例:刪除消息隊(duì)列#include #include #include int main()key_t key;int id;key=
15、ftok(.,1);id=msgget(key+1,IPC_CREAT|0666);printf(id=%dn,id);msgctl(id,IPC_RMID,NULL);sytem(“ipcs”);2021-12-8人民郵電出版社出版楊宗德編著21發(fā)送信息到消息隊(duì)列 extern int msgsnd(int _msqid, _const void * _msgp, size_t _msgsz, int _msgflg)第一個(gè)參數(shù)msqid為指定的消息隊(duì)列標(biāo)識(shí)符(由msgget生成的消息隊(duì)列標(biāo)識(shí)符),即將消息添加到那個(gè)消息隊(duì)列中。第二個(gè)參數(shù)msgp為指向的用戶(hù)定義緩沖區(qū)。第三個(gè)參數(shù)為接收信息的
16、大小,其數(shù)據(jù)類(lèi)型為size_t,即unsigned int類(lèi)型。其大小為0到系統(tǒng)對(duì)消息隊(duì)列的限定值。第四個(gè)參數(shù)用來(lái)指定在達(dá)到系統(tǒng)為消息隊(duì)列鎖定的界限(如達(dá)到字?jǐn)?shù)限制)時(shí)應(yīng)采取的操作。2021-12-822發(fā)送信息到消息隊(duì)列(2) 第二個(gè)參數(shù)其定義如下:/come from /usr/include/linux/msg.h/*message buffer for msgsnd and msgrev calls */struct msgbuflong mtype; /*type of message */char mtext1; /*message text */mtype是一個(gè)正整數(shù),由產(chǎn)生消息
17、的進(jìn)程生成,用于表示消息的類(lèi)型,因此,接收進(jìn)程可以用來(lái)進(jìn)行消息選擇(消息隊(duì)列在存儲(chǔ)信息時(shí)是按發(fā)送的先后順序放置的)。mtext是文本內(nèi)容,即消息內(nèi)容,此處大小為1,顯然不夠用,在使用時(shí)自己重新定義此結(jié)構(gòu)。2021-12-823發(fā)送信息到消息隊(duì)列(3)第四個(gè)參數(shù)用來(lái)指定在達(dá)到系統(tǒng)為消息隊(duì)列鎖定的界限(如達(dá)到字?jǐn)?shù)限制)時(shí)應(yīng)采取的操作。:如果設(shè)置為IPC_NOWAIT,如果需要等待,則不發(fā)送消息并且調(diào)用進(jìn)程立即返回錯(cuò)誤信息EAGAIN.如果設(shè)置為0,則忽略標(biāo)志位。成功調(diào)用后,此函數(shù)將返回0,否則返回-1,同時(shí)將對(duì)消息隊(duì)列msqid數(shù)據(jù)結(jié)構(gòu)的成員執(zhí)行下列操作:msg_qnum以1為增量遞增。msg_l
18、spid設(shè)置為調(diào)用進(jìn)程的進(jìn)程ID。msg_stime設(shè)置為當(dāng)前時(shí)間。2021-12-824從消息隊(duì)列接收信息extern int msgrev(int _msqid,void * _msgp, size_t _msgsz, long int _msgtyp, int _msgflg);此函數(shù)從與msqid指定的消息隊(duì)列標(biāo)識(shí)符相關(guān)聯(lián)的隊(duì)列中讀取消息,并將其放置到msgp指向的結(jié)構(gòu)中。第一個(gè)參數(shù)為讀的對(duì)象,即從哪個(gè)消息隊(duì)列獲得消息。第二個(gè)參數(shù)為一個(gè)臨時(shí)消息數(shù)據(jù)結(jié)構(gòu),用來(lái)保存讀取的信息。其定義與發(fā)送信息的第二個(gè)參數(shù)相同。第三個(gè)參數(shù)msgsz指定mtext的大小(以字節(jié)為單位)。如果收到的消息大于ms
19、gsz,并且msgflg&MSG_NOERROR為真,則將該消息截至msgsz字節(jié),消息的截?cái)嗖糠謱G失,并且不向調(diào)用進(jìn)程提供截?cái)嗟奶崾?021-12-825從消息隊(duì)列接收信息(2) 第四個(gè)參數(shù)msgtyp指定請(qǐng)求的消息類(lèi)型:msgtyp=0 收到隊(duì)列中的第一條消息,任意類(lèi)型。msgtyp0 收到第一條msgtyp類(lèi)型的消息。msgtyp0收到第一條最低類(lèi)型(小于或等于msgtyp的絕對(duì)值)的消息。第五個(gè)參數(shù)msgflg指定所需類(lèi)型消息不在隊(duì)列上時(shí)將要采取的操作。0,表示忽略;IPC_NOWAIT,如果消息隊(duì)列為空,則返回一個(gè)ENOMSG,并將控制權(quán)交回調(diào)用函數(shù)的進(jìn)程。2021-12-
20、826消息隊(duì)列應(yīng)用實(shí)例 #include #include #include #include #include #include #include struct msgmbuflong msg_type;char msg_text512;2021-12-827消息隊(duì)列應(yīng)用實(shí)例 int main()int qid;key_t key;int len;struct msgmbuf msg;if(key=ftok(.,a)=-1)perror(ftok);exit(EXIT_FAILURE);if(qid=msgget(key,IPC_CREAT|0666)=-1)perror(msgget);e
21、xit(EXIT_FAILURE);2021-12-828消息隊(duì)列應(yīng)用實(shí)例 printf(ID of the queue is: %dn,qid);puts(please input the mssage:);if(fgets(&msg)-msg_text,512,stdin)=NULL) puts(no message!);exit(EXIT_FAILURE);msg.msg_type=getpid();len=strlen(msg.msg_text);if(msgsnd(qid,&msg,len,0)0)perror(msgsnd);exit(EXIT_FAILURE);2
22、021-12-829消息隊(duì)列應(yīng)用實(shí)例 if(msgrcv(qid,&msg,512,0,0)msg_text);if(msgctl(qid,IPC_RMID,NULL)0)perror(msgctl);exit(EXIT_FAILURE);exit(0);2021-12-830第5章System V進(jìn)程間通信 System VIPC基礎(chǔ)基礎(chǔ) 消息隊(duì)列消息隊(duì)列 信號(hào)量通信機(jī)制信號(hào)量通信機(jī)制 共享內(nèi)存共享內(nèi)存 信號(hào)量基本概念信號(hào)量是操作系統(tǒng)中解決進(jìn)程或線程同步與互斥的最重要機(jī)制之一。Linux內(nèi)核提供System V的信號(hào)量機(jī)制,用于實(shí)現(xiàn)進(jìn)程之間通信。信號(hào)量常用系統(tǒng)調(diào)用見(jiàn)下表函數(shù)函數(shù)功能功
23、能sem_init初始化一個(gè)信號(hào)量sem_wait阻塞線程sem_post增加信號(hào)量的值sem_destory釋放信號(hào)量2021-12-832信號(hào)量集合屬性2021-12-833信號(hào)量結(jié)構(gòu) /come from /usr/src/kernels/uname -r/include/linux/sem.h/* One semaphore structure for each semaphore in the system. */struct semint semval; /* current value */int sempid; /* pid of last operation */;2021-
24、12-834信號(hào)量通信機(jī)制概念圖 2021-12-835創(chuàng)建信號(hào)量集合 extern int semget(key_t _key, int _nsems, int _semflg);第一個(gè)參數(shù)為key_t類(lèi)型的key值,一般由ftok函數(shù)產(chǎn)生。第二個(gè)參數(shù)_nsems為創(chuàng)建的信號(hào)量個(gè)數(shù),各信號(hào)量以數(shù)組的方式存儲(chǔ)。這個(gè)數(shù)組用于初始化數(shù)組對(duì)象。第三個(gè)參數(shù)_semflg用來(lái)標(biāo)識(shí)信號(hào)量集合的權(quán)限。如0770,為文件的訪問(wèn)權(quán)限類(lèi)型。此外,還可以附加以下參數(shù)值。這些值可以與基本權(quán)限以或的方式一起使用。/come from /usr/include/bit/ipc.h/*resource get reques
25、t flags */#define IPC_CREAT 00001000 /*create if key is non existent */#define IPC_EXCL 00002000 /*fail if key exists */#define IPC_NOWAIT 00004000 /*return error on wait */2021-12-836控制信號(hào)量集合、信號(hào)量extern int semctl(int _semid, int _semnum, int _cmd,)該函數(shù)最多可有四個(gè)參數(shù)(有可能只有三個(gè)參數(shù))。第一個(gè)參數(shù)_semid為要操作的信號(hào)量集合標(biāo)識(shí)符,該值一般
26、由semget函數(shù)返回。第二個(gè)參數(shù)為集合中信號(hào)量的編號(hào)。如果標(biāo)識(shí)某個(gè)信號(hào)量,此值為該信號(hào)量的下標(biāo)(從0到n-1);如果標(biāo)識(shí)整個(gè)信號(hào)量集合,則設(shè)置為0。第三個(gè)參數(shù)為要執(zhí)行的操作,如果是對(duì)整個(gè)信號(hào)量集合,這些操作在/usr/include/linux/ipc.h文件中定義。其操作包括IPC_RMID、IPC_SET、IPC_STAT和IPC_INFO,具體含義同msgctl的相關(guān)操作。2021-12-8372021-12-838信號(hào)量操作 extern int semop(int _semid, struct sembuf * _sops, size_t _nsops);此函數(shù)第一個(gè)參數(shù)為要操作的
27、信號(hào)量集合標(biāo)識(shí)符,該值一般由semget函數(shù)返回。第二個(gè)參數(shù)為struct sembuf結(jié)構(gòu)的變量,其定義如下:/come from /usr/include/linux/sem.h/* semop system calls takes an array of these. */struct sembuf unsigned short sem_num; /* semaphore index in array */short sem_op; /*semaphore operation */short sem_flg; /* operation flags */2021-12-839信號(hào)量操作(2
28、) 此結(jié)構(gòu)體有三個(gè)成員變量。1) sem_num為操作的信號(hào)量編號(hào)。2)sem_op為作用于信號(hào)量的操作:該值如果為正整數(shù)表示增加信號(hào)量的值,如果為負(fù)整數(shù)表示減小信號(hào)量的值,如果為0表示對(duì)信號(hào)量的當(dāng)前值進(jìn)行是否為0的測(cè)試。3)sem_flg為操作標(biāo)識(shí)。2021-12-840使用信號(hào)量實(shí)現(xiàn)生產(chǎn)消費(fèi)問(wèn)題 生產(chǎn)消費(fèi)問(wèn)題是一個(gè)經(jīng)典的數(shù)學(xué)問(wèn)題,要求生產(chǎn)者消費(fèi)者在固定的倉(cāng)庫(kù)空間條件下,生產(chǎn)者每生產(chǎn)一個(gè)產(chǎn)品將占用一個(gè)倉(cāng)庫(kù)空間,生產(chǎn)者生產(chǎn)的產(chǎn)品庫(kù)存不能越過(guò)倉(cāng)庫(kù)的存儲(chǔ)量,消費(fèi)者每消費(fèi)一個(gè)產(chǎn)品將增加一個(gè)倉(cāng)庫(kù)空間,消費(fèi)者在倉(cāng)庫(kù)產(chǎn)品為0時(shí)不能再消費(fèi)。本例中采用信號(hào)量來(lái)解決這個(gè)問(wèn)題,為了便于理解,本例中使用了兩個(gè)信號(hào)量
29、,一個(gè)用來(lái)管理消費(fèi)者(以下為sem_produce),一個(gè)用來(lái)管理生產(chǎn)者(以下為sem_custom),即sem_produce表示當(dāng)前倉(cāng)庫(kù)可用空間的數(shù)量,sem_custom用來(lái)表示當(dāng)前倉(cāng)庫(kù)中產(chǎn)品的數(shù)量。對(duì)于生產(chǎn)者來(lái)說(shuō),其需要申請(qǐng)的資源為倉(cāng)庫(kù)中的剩余空間,因此,生產(chǎn)者在生產(chǎn)一個(gè)產(chǎn)品前,申請(qǐng)sem_produce信號(hào)量,當(dāng)此信號(hào)量的值大于0,即有可用空間,將生產(chǎn)產(chǎn)品,并將sem_produce的值減去1(因?yàn)檎加昧艘粋€(gè)空間);同時(shí),當(dāng)其生產(chǎn)一個(gè)產(chǎn)品后,當(dāng)前倉(cāng)庫(kù)的產(chǎn)品數(shù)量增加1,需要將sem_custom信號(hào)量自動(dòng)加1。對(duì)于消費(fèi)者來(lái)說(shuō),其需要申請(qǐng)的資源為倉(cāng)庫(kù)中的產(chǎn)品,因此,消費(fèi)者在消費(fèi)一個(gè)產(chǎn)品前
30、,將申請(qǐng)sem_custom信號(hào)量,當(dāng)此信號(hào)量的值大于0時(shí),即有可用產(chǎn)品,將消費(fèi)一個(gè)產(chǎn)品,并將sem_custom信號(hào)量的值減去(因?yàn)橄M(fèi)了一個(gè)產(chǎn)品),同時(shí),當(dāng)消費(fèi)一個(gè)產(chǎn)品,當(dāng)前倉(cāng)庫(kù)的剩余空間增加1,需要將sem_produce信號(hào)量自動(dòng)加1。2021-12-841第5章System V進(jìn)程間通信 System VIPC基礎(chǔ)基礎(chǔ) 消息隊(duì)列消息隊(duì)列 信號(hào)量通信機(jī)制信號(hào)量通信機(jī)制 共享內(nèi)存共享內(nèi)存 共享內(nèi)存的基本概念共享內(nèi)存允許兩個(gè)或多個(gè)進(jìn)程共享一個(gè)給定的存儲(chǔ)區(qū),這一段存儲(chǔ)區(qū)可以被兩個(gè)或兩個(gè)以上的進(jìn)程映射至自身的地址空間中,數(shù)據(jù)不需要在進(jìn)程間復(fù)制,所以這是最快的一種IPC。使用共享內(nèi)存時(shí),多個(gè)進(jìn)程
31、之間對(duì)一給定的存儲(chǔ)區(qū)需進(jìn)行同步訪問(wèn)。即若一個(gè)進(jìn)程正在將數(shù)據(jù)放入共享存儲(chǔ)區(qū),則在它做完這一操作之前,其他進(jìn)程不應(yīng)當(dāng)去讀取這些數(shù)據(jù)。通常,信號(hào)量被用來(lái)實(shí)現(xiàn)對(duì)共享存儲(chǔ)的訪問(wèn)。2021-12-843共享內(nèi)存屬性2021-12-844共享內(nèi)存IPC原理 2021-12-845共享內(nèi)存與管道對(duì)比 2021-12-846共享內(nèi)存的常用函數(shù)函數(shù)函數(shù)功能功能mmap建立共享內(nèi)存映射munmap解除共享內(nèi)存映射shmget獲取共享內(nèi)存區(qū)域的IDshmctl共享內(nèi)存控制shmat映射共享內(nèi)存對(duì)象shmdt分離共享內(nèi)存對(duì)象2021-12-847內(nèi)存映射函數(shù)mmap將某個(gè)文件的指定內(nèi)容映射到內(nèi)存空間中,該函數(shù)聲明如下:
32、#include void *mmap(void *start, size_t length,int prot, int flags, int fd, off_t offset);此函數(shù)將在進(jìn)程的虛擬地址空間(起始為start,長(zhǎng)度為length字節(jié))和與文件描述符fd關(guān)聯(lián)的文件(偏移量為offset,長(zhǎng)度為length)之間建立映射。參數(shù)start一般情況下設(shè)置為NULL,由系統(tǒng)分配。第三個(gè)參數(shù)prot描述映射的內(nèi)存權(quán)限,該參數(shù)是以下選項(xiàng)的組合:PORT_READ 允許讀該內(nèi)存 PORT_WRITE 允許寫(xiě)該內(nèi)存PORT_EXEC 允許執(zhí)行該內(nèi)存段 PORT_NONE 該內(nèi)存段不能被訪問(wèn)20
33、21-12-848內(nèi)存映射參數(shù)flags控制程序?qū)υ搩?nèi)存段的改變所造成的影響,常用選項(xiàng)如下:MAP_PRIVATE:內(nèi)存段是私有的,對(duì)他的修改只在此局部范圍內(nèi)有效,其他進(jìn)程不可見(jiàn)。MAP_SHARED:共享映射,某進(jìn)程對(duì)該段內(nèi)存空間的更新對(duì)其他進(jìn)程來(lái)說(shuō)是可見(jiàn)的,但該文件的內(nèi)容并不會(huì)立即更新,要更新文件內(nèi)容,需要調(diào)用msync和munmap函數(shù)。2021-12-849例:內(nèi)存映射的使用#include #include #include #include #include typedef structchar name4;int age;people;main(int argc, char *
34、argv)pid_t result; int i;people *p_map;char temp;2021-12-850例:內(nèi)存映射的使用p_map=(people *)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS, -1,0);result=fork();if(result0)perror(fork);exit(EXIT_FAILURE);else if(result=0)sleep(2);for(i=0;i5;i+)printf(read by child:No.%ds age is:%d
35、n,i+1,(*(p_map+i).age);2021-12-851例:內(nèi)存映射的使用(*p_map).age=110;munmap(p_map,sizeof(people)*10);exit(0);elsetemp=a;for(i=0;iname, &temp,2);(p_map+i)-age=20+i);2021-12-852例:內(nèi)存映射的使用sleep(5);printf(read by parent:the sum of age is:%dn,(*p_map).age);printf(unmapingn);munmap(p_map,sizeof(people)*10);prin
36、tf(unmap successful!n);2021-12-853創(chuàng)建共享內(nèi)存 extern int shmget(key_t _key, size_t _size, int _shmflg);第一個(gè)參數(shù)為key_t類(lèi)型的key值,一般由ftok函數(shù)產(chǎn)生。第二個(gè)參數(shù)size為欲創(chuàng)建的共享內(nèi)存段大小(單位為字節(jié))。第三個(gè)參數(shù)shmflg用來(lái)標(biāo)識(shí)共享內(nèi)存段的創(chuàng)建標(biāo)識(shí)。包括/come from /usr/include/linu/ipc.h#define IPC_CREAT 01000 /*Create key if key does not exist. */#define IPC_EXCL 0
37、20000 /*Fail if key exists. */#define IPC_NOWAIT 04000 /*Return error on wait. */2021-12-854創(chuàng)建共享內(nèi)存 另外,在 /usr/include /linux/shm.h文件還定義了另外兩個(gè)選項(xiàng):/come from /usr/include/linux/shm.h/*permission flag for shmget */#define SHM_R 0400 /*or S_IRUGO from */#define SHM_W 0200 /*or S_IWUGO from */2021-12-855共享內(nèi)
38、存控制 extern int shmctl(int _shmid, int _cmd, struct shmid_ds * _buf);第一個(gè)參數(shù)為要操作的共享內(nèi)存標(biāo)識(shí)符,該值一般由shmget函數(shù)返回。第二個(gè)參數(shù)為要執(zhí)行的操作,這些操作在/usr/include/linux/ipc.h文件中定義。其操作包括IPC_RMID、IPC_SET、IPC_STAT和IPC_INFO,具體含義同msgctl的相關(guān)操作。如果是超級(jí)用戶(hù),還可以執(zhí)行以下兩個(gè)命令:/come from /usr/include/sys/shm.h/* super user shmctl commands */#define
39、SHM_LOCK 11#define SHM_UNLOCK 12第三個(gè)參數(shù)為struct shmid_ds結(jié)構(gòu)的臨時(shí)共享內(nèi)存變量信息,此內(nèi)容根據(jù)第二個(gè)參數(shù)的不一樣而改變。2021-12-856映射共享內(nèi)存對(duì)象進(jìn)程使用共享內(nèi)存前,需要將該共享內(nèi)存與當(dāng)前進(jìn)程建立聯(lián)系,即將該共享內(nèi)存使用shmat函數(shù)映射到當(dāng)前進(jìn)程。其函數(shù)聲明如下:#include extern void *shmat(int _shmid, _const void *_shmaddr, int _shmflag);如果執(zhí)行成功,將返回共享內(nèi)存段首地址。第一個(gè)參數(shù)_shmid為要操作的共享內(nèi)存標(biāo)識(shí)符,該值一般由shmget函數(shù)返回。
40、第二個(gè)參數(shù)shmaddr指定共享內(nèi)存的映射地址。如果該值為非零,則將用此值作為映射共享內(nèi)存的地址,如果此值為0,則由系統(tǒng)來(lái)選擇映射的地址。一般都將此值設(shè)置為0。2021-12-857映射共享內(nèi)存對(duì)象#include extern void *shmat(int _shmid, _const void *_shmaddr, int _shmflag);第三個(gè)參數(shù)用來(lái)指定共享內(nèi)存短的訪問(wèn)權(quán)限和映射條件。/come from /usr/include/linux/shm.h/* mode for attach */#define SHM_RDNOLY 010000 /*read-only acces
41、s */#define SHM_RND 020000 /*round attach attach address to SHMLBA bounary */#define SHM_REMAP 040000 /*take-over region on attach */#define SHM_EXEC 0100000 /*execution access */2021-12-858分離共享內(nèi)存對(duì)象在共享內(nèi)存使用完畢后,需要使用shmdt函數(shù)將其與當(dāng)前進(jìn)程分離。其函數(shù)聲明如下:/come from /usr/include/sys/shm.hextern int shmdt(_const void
42、*_shmaddr);其參數(shù)即為與當(dāng)前進(jìn)程分離的共享內(nèi)存標(biāo)志ID。2021-12-859例一#include #include #include #include #include #include typedef structchar name4;int age;people;main()int shm_id, i; key_t key;people *p_map;char * name=/dev/shm/myshm2;2021-12-860例一key=ftok(name,0);shm_id=shmget(key,4096,IPC_CREAT);if(shm_id=-1)perror(shm
43、get);exit(EXIT_FAILURE);p_map=(people *)shmat(shm_id,NULL, 0);for(i=0;iname);printf(age :%dn,(p_map+i)-age);if(shmdt(p_map)=-1)perror(shmdt);2021-12-861例一#include #include #include #include #include #include typedef structchar name4;int age;people;main()int shm_id, i; key_t key;people *p_map;char *
44、name=/dev/shm/myshm2;2021-12-862例一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;iname,&temp,1);(p_map+i)-age=20+i;if(shmdt(p_map)
45、=-1)perror(shmdt);2021-12-8人民郵電出版社出版楊宗德編著63例二#include #include #include #include #include #include #include typedef structchar str150;char str250;int no1,no2;str;2021-12-864例二main(int argc, char * agv)int shm_id,i; key_t key;str *p_map;time_t timep;struct tm *p; char * name=/dev/shm/myshm2;key=ftok(name,0);shm_id=shmget(key,4096,IPC_CREAT|0666);if(shm_id=-1)perror(shmge
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 航空航天復(fù)合材料 課件知識(shí)點(diǎn)6 高熵合金基復(fù)合材料
- 會(huì)滾的汽車(chē)課件
- 剪輯技巧培訓(xùn)課件
- 腫瘤科常用藥物臨床應(yīng)用與管理
- 路基工程這知識(shí)培訓(xùn)
- 2025年 安康市紫陽(yáng)縣民歌藝術(shù)研究中心招聘考試筆試試卷附答案
- 2025年中國(guó)噴泉套件行業(yè)市場(chǎng)全景分析及前景機(jī)遇研判報(bào)告
- 小動(dòng)物搬家課件
- 蛛網(wǎng)膜下腔出血疑難病例討論
- 紅血絲皮膚的成因及護(hù)理
- 寵物清潔衛(wèi)生用品貓砂
- 大模型備案-落實(shí)算法安全主體責(zé)任基本情況-XX集團(tuán)有限公司
- 護(hù)理禮儀與人際溝通試題(含答案)
- 2025-2030中國(guó)蔬菜溫室大棚市場(chǎng)消費(fèi)趨勢(shì)分析與經(jīng)營(yíng)管理風(fēng)險(xiǎn)報(bào)告
- 學(xué)校外來(lái)人員登記制度
- 應(yīng)急物資中轉(zhuǎn)站項(xiàng)目可行性研究報(bào)告(模板范文)
- 2025年初級(jí)等保測(cè)評(píng)試題及答案
- 薄壁空心墩施工方案
- 多重耐藥菌醫(yī)院感染預(yù)防與控制技術(shù)指南(試行)
- 教師如何使用AI開(kāi)展教學(xué)DeepSeek使用指南人工智能 課件
- 油氣田地面工程詳解
評(píng)論
0/150
提交評(píng)論