版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍Linux進(jìn)程間通信(下)Linux IPC programme桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)課程目標(biāo)lSystem V IPC 接口簡(jiǎn)介System V 消息隊(duì)列消息隊(duì)列System V 信號(hào)量System V 共享內(nèi)存lPOSIX IPC接口Posix 消息隊(duì)列Posix 信號(hào)量信號(hào)量Posix 共享內(nèi)存共享內(nèi)存Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)System V IPC 接口l由于歷史原因, linux下
2、的進(jìn)程通信手段基本上是從Unix平臺(tái)上的進(jìn)程通信手段繼承而來(lái)的 .lUnix發(fā)展做出重大貢獻(xiàn)的兩大主力AT&T的貝爾實(shí)驗(yàn)室及BSD(加州大學(xué)伯克利分校的伯克利軟件發(fā)布中心)在進(jìn)程間通信方面的側(cè)重點(diǎn)有所不同 貝爾實(shí)驗(yàn)室對(duì)Unix早期的進(jìn)程間通信手段進(jìn)行了系統(tǒng)的改進(jìn)和擴(kuò)充,形成了“system V IPC”,通信進(jìn)程局限在單個(gè)計(jì)算機(jī)內(nèi) .BSD則形成了基于套接口(socket)的進(jìn)程間通信機(jī)制 ,可以在跨機(jī)器進(jìn)行通信.l由于Unix版本的多樣性,電子電氣工程協(xié)會(huì)(IEEE)開(kāi)發(fā)了一個(gè)獨(dú)立的Unix標(biāo)準(zhǔn),這個(gè)新的ANSI Unix標(biāo)準(zhǔn)被稱(chēng)為計(jì)算機(jī)環(huán)境的可移植性操作系統(tǒng)界面(POSIX)。 他
3、也發(fā)展出一套新的IPC接口.Linux 本身支持POSIX接口.因此也支持POSIX的IPC接口l最初Unix IPC包括:管道、FIFO、信號(hào) , System V IPC包括:System V消息隊(duì)列、System V信號(hào)燈、System V共享內(nèi)存區(qū) , Posix IPC包括: Posix消息隊(duì)列、Posix信號(hào)燈、Posix共享內(nèi)存區(qū)。l System V IPC通常在多個(gè)操作系統(tǒng)均實(shí)現(xiàn),包括一般的嵌入式Linux系統(tǒng),因此本課程主要介紹system V IPCLinux 培培訓(xùn)訓(xùn)Linux 的IPCLinux 培培訓(xùn)訓(xùn)lSystemV IPC指以下三種類(lèi)型的IPC:SystemV消
4、息隊(duì)列 sys/msg.hSystemV信號(hào)燈 sys/sem.hSystemV共享內(nèi)存區(qū) sys/shm.hl創(chuàng)建或打開(kāi)函數(shù)創(chuàng)建或打開(kāi)函數(shù)msgget,semget,shmgetl控制操作函數(shù)控制操作函數(shù)msgctl,semctl,shmctll操作函數(shù)操作函數(shù) msgsnd,msgrcv,semop,shmat,shmdtLinux 培培訓(xùn)訓(xùn)System V關(guān)鍵字l每一個(gè)System V 對(duì)象(消息隊(duì)列,共享內(nèi)存和信號(hào)量)創(chuàng)建時(shí),需要的第一個(gè)參數(shù)是整數(shù)的Key值,頭文件把key_t定義為一個(gè)整數(shù)lSystem V 創(chuàng)建對(duì)象時(shí)假設(shè)進(jìn)行IPC通訊雙方都取了相同的key值.這樣將雙方關(guān)聯(lián)起來(lái)l生
5、成key的方法有三種雙方直接設(shè)置為一個(gè)相同的整數(shù)為key值用IPC_PRIVA讓系統(tǒng)自動(dòng)產(chǎn)生一個(gè)key值,用ftok函數(shù)將一個(gè)路徑轉(zhuǎn)換為key值Linux 培培訓(xùn)訓(xùn)ftok函數(shù)lftok函數(shù)把一個(gè)已存在的路徑名和一個(gè)整數(shù)標(biāo)識(shí)符轉(zhuǎn)換成一個(gè)key_t值,稱(chēng)為IPC鍵(IPC key):#include key_t ftok(const char *pahtname, int id);l如果pathname不存在,或者對(duì)調(diào)用進(jìn)程不可訪問(wèn),ftok返回-1 l不能保證兩個(gè)不同的路徑名與同一個(gè)id值的組合產(chǎn)生不同的鍵。 l用于產(chǎn)生鍵的pahtname不能是服務(wù)器存活期間由它反復(fù)創(chuàng)建并刪除的文件,否則會(huì)導(dǎo)
6、致ftok多次調(diào)用返回不同的值 Linux 培培訓(xùn)訓(xùn)System V IPC的類(lèi)型l報(bào)文(Message)隊(duì)列(消息隊(duì)列):消息隊(duì)列是消息的鏈接表,包括Posix消息隊(duì)列system V消息隊(duì)列。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息。消息隊(duì)列克服了信號(hào)承載信息量少,管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。 l共享內(nèi)存:使得多個(gè)進(jìn)程可以訪問(wèn)同一塊內(nèi)存空間,是最快的可用IPC形式。是針對(duì)其他通信機(jī)制運(yùn)行效率較低而設(shè)計(jì)的。往往與其它通信機(jī)制,如信號(hào)量結(jié)合使用,來(lái)達(dá)到進(jìn)程間的同步及互斥。l信號(hào)量(semaphore):主要作為進(jìn)程間以及同一進(jìn)程不同線
7、程之間的同步手段。 Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)消息隊(duì)列l(wèi)消息隊(duì)列就是一個(gè)消息的鏈表??梢园严⒖醋饕粋€(gè)記錄,具有特定的格式以及特定的優(yōu)先級(jí)。對(duì)消息隊(duì)列有寫(xiě)權(quán)限的進(jìn)程可以向中按照一定的規(guī)則添加新消息;對(duì)消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀走消息。 l消息隊(duì)列能夠克服早期unix通信機(jī)制的一些缺點(diǎn) ,如數(shù)據(jù)量小,沒(méi)有實(shí)時(shí)性Linux 培培訓(xùn)訓(xùn)消息隊(duì)列(2)l消息隊(duì)列消息通常要以一個(gè)long mtype放在消息開(kāi)始, mtype成員代表消息類(lèi)型,從消息隊(duì)列中讀取消息的一個(gè)重要依據(jù)就是消息的類(lèi)型s
8、truct msgbuf long mtype; char mtext1; ; l消息隊(duì)列與管道以及有名管道相比,具有更大的靈活性 它提供有格式字節(jié)流,有利于減少開(kāi)發(fā)人員的工作量 消息具有類(lèi)型,在實(shí)際應(yīng)用中,可作為優(yōu)先級(jí)使用。這兩點(diǎn)是管道以及有名管道所不能比的 消息隊(duì)列可以在幾個(gè)進(jìn)程間復(fù)用,而不管這幾個(gè)進(jìn)程是否具有親緣關(guān)系,這一點(diǎn)與有名管道很相似;但消息隊(duì)列是隨內(nèi)核持續(xù)的,與有名管道(隨進(jìn)程持續(xù))相比,生命力更強(qiáng),應(yīng)用空間更大。 Linux 培培訓(xùn)訓(xùn)消息隊(duì)列編程l頭文件#include #include #include lmsgget打開(kāi)或創(chuàng)建消息隊(duì)列int msgget(key_t key
9、, int msgflg) ;返回線隊(duì)列IDlmsgrcv從隊(duì)列接收消息int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg); lmsgsnd 向隊(duì)列發(fā)送消息int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg); lmsgctl 發(fā)送隊(duì)列控制命令msgctl(int msqid, int cmd, struct msqid_ds *buf); 共有三種cmd操作:IPC_STAT、IPC_SET 、IPC_RMID
10、。 Linux 培培訓(xùn)訓(xùn)消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)l對(duì)于系統(tǒng)中的每個(gè)System V消息隊(duì)列,內(nèi)核維護(hù)一個(gè)如下的結(jié)構(gòu):struct msqid_ds struct ipc_perm msg_perm; /* operation permission struct */ struct msg *msg_first; /* ptr to first message on q */ struct msg *msg_last; /* ptr to last message on q */ unsigned short msg_cbytes; /* current # bytes on q */ msgqnum_
11、t msg_qnum; /* # of messages on q */ msglen_t msg_qbytes; /* max # of bytes on q */ pid_t msg_lspid; /* pid of last msgsnd */ pid_t msg_lrpid; /* pid of last msgrcv */ time_t msg_stime; /* last msgsnd time */ time_t msg_rtime; /* last msgrcv time */ time_t msg_ctime; /* last change time */;Linux 培培訓(xùn)
12、訓(xùn)msgget函數(shù) l#include lint msgget(key_t key, int oflag);返回:成功時(shí)為非負(fù)標(biāo)識(shí)符,出錯(cuò)時(shí)為-1用于創(chuàng)建一個(gè)新的SystemV消息隊(duì)列或訪問(wèn)一個(gè)已經(jīng)存在的消息隊(duì)列。l參數(shù)key和oflag的說(shuō)明見(jiàn)前。lOflag :取值取值,IPC_CREAT 創(chuàng)建新對(duì)象成功,IPC_EXCL檢查新對(duì)象l返回值是一個(gè)整數(shù)標(biāo)識(shí)符,其他三個(gè)msg函數(shù)用它來(lái)指代該隊(duì)列。l當(dāng)創(chuàng)建一個(gè)消息隊(duì)列時(shí),msqid_ds結(jié)構(gòu)的如下成員被初始化:msg_perm結(jié)構(gòu)的uid和cuid被設(shè)置為當(dāng)前進(jìn)程的有效用戶(hù)ID,gid和cgid被設(shè)置為當(dāng)前用戶(hù)的有效組ID; oflag中的讀寫(xiě)
13、權(quán)限位存放在msg_perm.mode中; msg_qnum、msg_lspid、msg_lrpid、msg_stime和msg_rtime被置為0; msg_ctime被設(shè)置成當(dāng)前時(shí)間; msg_qbytes被設(shè)置為系統(tǒng)限制值。 Linux 培培訓(xùn)訓(xùn)msgsnd函數(shù) l#include lint msgsnd(int msgid, const void *ptr, size_t length, int flag);l返回:成功時(shí)為0,出錯(cuò)時(shí)為-1l該函數(shù)用于往消息隊(duì)列上放置一個(gè)消息。lmsgid是msgget返回的標(biāo)識(shí)符,ptr是一個(gè)結(jié)構(gòu)指針,該結(jié)構(gòu)有如下的模板:struct msgbuf
14、long mtype; /* message type, must be 0 */ char mtext 1 ; /* message data */;l消息類(lèi)型mtype必須大于0,因?yàn)榉钦㈩?lèi)型有特殊的指示作用。llength參數(shù)以字節(jié)為單位指定待發(fā)送消息的長(zhǎng)度。這是位于長(zhǎng)整數(shù)消息類(lèi)型之后的用戶(hù)自定義數(shù)據(jù)的長(zhǎng)度,該長(zhǎng)度可以是0。lflag參數(shù)可以是0,也可以是IPC_NOWAIT。IPC_NOWAIT標(biāo)志使得msgsnd調(diào)用非阻塞。當(dāng)有如下情形之一時(shí):在指定的隊(duì)列中已經(jīng)有太多的字節(jié)(對(duì)應(yīng)msqid_ds結(jié)構(gòu)中的msg_qbytes值); 在系統(tǒng)范圍存在太多的消息。 若設(shè)置了IPC_NOW
15、AIT,則msgsnd立即返回,返回一個(gè)EAGAIN錯(cuò)誤。若未指定該標(biāo)志,則msgsnd阻塞,直到具備存放新消息的空間; 有msgid標(biāo)識(shí)的消息隊(duì)列被刪除,此時(shí)返回EIDRM錯(cuò)誤; 被信號(hào)中斷,此時(shí)返回EINTR錯(cuò)誤。Linux 培培訓(xùn)訓(xùn)msgrcv函數(shù) l#include lssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag);l返回:成功時(shí)為讀入緩沖區(qū)中數(shù)據(jù)的字節(jié)數(shù),出錯(cuò)時(shí)為-1l該函數(shù)從某個(gè)消息隊(duì)列中讀出一個(gè)消息。lptr參數(shù)指定所接收消息的存放位置。跟msgsnd一樣,該指針指向緊挨在真正的消息
16、數(shù)據(jù)之前返回的長(zhǎng)整數(shù)類(lèi)型字段。llength指定由ptr指向的緩沖區(qū)中數(shù)據(jù)部分的大小。這是該函數(shù)能返回的最大數(shù)據(jù)量。該長(zhǎng)度不包含長(zhǎng)整數(shù)類(lèi)型字段。ltype指定希望從所給定的隊(duì)列中讀出什么樣的消息:type為0,返回隊(duì)列中第一個(gè)消息。每個(gè)消息隊(duì)列是作為一個(gè)FIFO鏈表維護(hù)的,所以返回的是隊(duì)列中最早的消息。 type大于0,返回其類(lèi)型值為type的第一個(gè)消息。 type小于0,返回其類(lèi)型值小于或等于type參數(shù)的絕對(duì)值的消息中類(lèi)型值最小的第一個(gè)消息。 lflag參數(shù)指定所請(qǐng)求的消息不在隊(duì)列中時(shí)怎么辦。在沒(méi)有消息時(shí),若設(shè)置了IPC_NOWAIT標(biāo)志,則函數(shù)立即返回一個(gè)ENOMSG錯(cuò)誤;否則,調(diào)用者阻
17、塞直到如下某個(gè)時(shí)間發(fā)生:l有一個(gè)所請(qǐng)求類(lèi)型的消息可獲??; l由msqid標(biāo)識(shí)的消息隊(duì)列被刪除,此時(shí)返回個(gè)EIDRM錯(cuò)誤; l被某個(gè)捕獲的信號(hào)中斷,此時(shí)返回EINTR錯(cuò)誤。 Linux 培培訓(xùn)訓(xùn)msgctl函數(shù) l#include lint msgctl(int msqid, int cmd, struct msqid_ds *buf);l返回:成功時(shí)為0,出錯(cuò)時(shí)為-1l該函數(shù)提供在一個(gè)消息隊(duì)列上的各種控制操作。lmsgctl提供三個(gè)命令:IPC_RMID:從系統(tǒng)中刪除由msqid指定的消息隊(duì)列。當(dāng)前在該隊(duì)列上的任何消息都被丟棄。此時(shí)。第三個(gè)參數(shù)忽略不用。 IPC_SET:給指定的消息隊(duì)列設(shè)置其
18、msqid_ds結(jié)構(gòu)的以下四個(gè)成員:msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_perm.qbytes。它們的值來(lái)自buff指向的結(jié)構(gòu)中的相應(yīng)成員。 IPC_STAT:通過(guò)buff參數(shù)給調(diào)用者返回所指定消息隊(duì)列中的當(dāng)前msqid_ds結(jié)構(gòu)。Linux 培培訓(xùn)訓(xùn)消息隊(duì)列打開(kāi)l如果沒(méi)有調(diào)用 msgctl(semid,IPC_RMID,0)刪除消息隊(duì)列,則消息隊(duì)列一直存在內(nèi)核中,即便是創(chuàng)建進(jìn)程已經(jīng)退出也是如此,這個(gè)用ipcs可以看到l如果對(duì)一個(gè)已經(jīng)創(chuàng)建的消息隊(duì)列的路徑再次創(chuàng)建消息隊(duì)列,通常都會(huì)出錯(cuò).因此可以采用一種保險(xiǎn)的寫(xiě)法/* 首先查詢(xún)這個(gè)隊(duì)列是否創(chuàng)建,
19、如創(chuàng)建直接用它*/if(msgid =msgget(key,IPC_EXCL|0666) = -1)/*沒(méi)有創(chuàng)建才去創(chuàng)建這個(gè)消息隊(duì)列*/msgid=msgget(key,IPC_CREAT|IPC_EXCL|00666);if(msgid=-1) printf(msg create errorn); return;l其它對(duì)象也用這樣打開(kāi)方法Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)信號(hào)量l信號(hào)量與其他進(jìn)程間通信方式不大相同,它主要提供對(duì)進(jìn)程間共享資源訪問(wèn)控制機(jī)制。 l信號(hào)量相當(dāng)是一個(gè)全局的整數(shù)變量,這個(gè)變量只能
20、用原子操作來(lái)改變值l信號(hào)燈與其它進(jìn)程間通信方式有所不同,它主要用于進(jìn)程間同步。通常所說(shuō)的系統(tǒng)V信號(hào)燈實(shí)際上是一個(gè)信號(hào)燈的集合,可用于多種共享資源的進(jìn)程間同步。每個(gè)信號(hào)燈都有一個(gè)值,可以用來(lái)表示當(dāng)前該信號(hào)燈代表的共享資源可用(available)數(shù)量,l如果一個(gè)進(jìn)程要申請(qǐng)共享資源,那么就從信號(hào)燈值中減去要申請(qǐng)的數(shù)目,如果當(dāng)前沒(méi)有足夠的可用資源,進(jìn)程可以睡眠等待,也可以立即返回。當(dāng)進(jìn)程要申請(qǐng)多種共享資源時(shí),linux可以保證操作的原子性,即要么申請(qǐng)到所有的共享資源,要么放棄所有資源,這樣能夠保證多個(gè)進(jìn)程不會(huì)造成互鎖。 Linux 培培訓(xùn)訓(xùn)信號(hào)量集的數(shù)據(jù)結(jié)構(gòu)lSystemV信號(hào)燈是信號(hào)燈集的概念:一
21、個(gè)或多個(gè)信號(hào)燈構(gòu)成一個(gè)集合。對(duì)于系統(tǒng)每個(gè)信號(hào)燈集,內(nèi)核維護(hù)如下的一個(gè)結(jié)構(gòu):struct semid_ds struct ipc_perm sem_perm; /* operation permission struct */ struct sem *sem_base; /* ptr to first semaphore in set */ unsigned short sem_nsems; /* # of semaphores in set */ time_t sem_otime; /* last semop time */ time_t sem_ctime; /* last change t
22、ime */;l當(dāng)前信號(hào)燈集中的每個(gè)信號(hào)燈對(duì)應(yīng)一個(gè)sem結(jié)構(gòu)。定義如下:struct sem signed short semval; /* semaphore text map address */ pid_t sempid; /* pid of last operation */ unsigned short semncnt; /* # awaiting semval cval */ unsigned short semzcnt; /* # awaiting semval = 0 */;Linux 培培訓(xùn)訓(xùn)關(guān)于關(guān)于P原語(yǔ)原語(yǔ)lP原語(yǔ):原語(yǔ):P是荷蘭語(yǔ)Proberen(測(cè)試)的首字母。為阻塞
23、原語(yǔ),負(fù)責(zé)把當(dāng)前進(jìn)程由運(yùn)行狀態(tài)轉(zhuǎn)換為阻塞狀態(tài),直到另外一個(gè)進(jìn)程喚醒它。操作為:申請(qǐng)一個(gè)空閑資源(把信號(hào)量減1),若成功,則退出;若失敗,則該進(jìn)程被阻塞;P原語(yǔ)的操作過(guò)程lsem減1;l若sem減1后仍大于或等于零,則進(jìn)程繼續(xù)執(zhí)行;l若sem減1后小于零,則該進(jìn)程被阻塞后進(jìn)入與該信號(hào)相對(duì)應(yīng)的隊(duì)列中,然后轉(zhuǎn)進(jìn)程調(diào)度。System V 實(shí)現(xiàn)代碼 int p(int semid) struct sembuf sops=0,+1,IPC_NOWAIT; return (semop(semid,&sops,1);Linux 培培訓(xùn)訓(xùn)關(guān)于關(guān)于V原語(yǔ)原語(yǔ)lV原語(yǔ)V是荷蘭語(yǔ)Verhogen(增加)的首字
24、母。為喚醒原語(yǔ),負(fù)責(zé)把一個(gè)被阻塞的進(jìn)程喚醒,它有一個(gè)參數(shù)表,存放著等待被喚醒的進(jìn)程信息。操作為:釋放一個(gè)被占用的資源(把信號(hào)量加1),如果發(fā)現(xiàn)有被阻塞的進(jìn)程,則選擇一個(gè)喚醒之V原語(yǔ)的操作過(guò)程lsem加1; l若相加結(jié)果大于零,則進(jìn)程繼續(xù)執(zhí)行; l 若相加結(jié)果小于或等于零,則從該信號(hào)的等待隊(duì)列中喚醒一等待進(jìn)程,然后再返回原進(jìn)程繼續(xù)執(zhí)行或轉(zhuǎn)進(jìn)程調(diào)度。 System V 實(shí)現(xiàn)代碼int v(int semid) struct sembuf sops=0,-1,IPC_NOWAIT; return (semop(semid,&sops,1);Linux 培培訓(xùn)訓(xùn)信號(hào)量的處理流程信號(hào)量的處理流程
25、 l用到頭文件#include #include #include lsemget創(chuàng)建或打開(kāi)一個(gè)信號(hào)量int semget(key_t key, int nsems, int semflg) lSemop()對(duì)信號(hào)量 +1 或 -1 或測(cè)試是否為0 int semop(int semid, struct sembuf *sops, unsigned nsops); linux可以增加或減小信號(hào)量的值,相應(yīng)于對(duì)共享資源的釋放和占有 lsemctl 對(duì)信號(hào)量進(jìn)行各種控制int semctl(int semid,int semnum,int cmd,union semun arg) Linux 培培
26、訓(xùn)訓(xùn)semget函數(shù) l#include lint semget(key_t key, int nsems, int oflag);l返回:成功時(shí)為非負(fù)標(biāo)識(shí)符,出錯(cuò)時(shí)為-1l創(chuàng)建一個(gè)信號(hào)燈集或訪問(wèn)一個(gè)已存在的信號(hào)燈集。l返回值是信號(hào)燈標(biāo)識(shí)符,供其他信號(hào)燈函數(shù)使用。lnsems是集合中的信號(hào)燈數(shù)。如果不是創(chuàng)建一個(gè)信號(hào)燈集,而只是訪問(wèn)已存在的集合,則該參數(shù)可以指定為0。一旦創(chuàng)建完畢一個(gè)信號(hào)燈集,就不能改變其中的信號(hào)燈數(shù)。l當(dāng)實(shí)際操作為創(chuàng)建一個(gè)新的信號(hào)燈集時(shí),semid_ds結(jié)構(gòu)的以下成員將被初始化:sem_perm結(jié)構(gòu)的uid和cuid被設(shè)置為調(diào)用進(jìn)程的有效用戶(hù)ID,gid和cgid被設(shè)置為調(diào)用進(jìn)
27、程的有效組ID; oflag參數(shù)中的讀寫(xiě)權(quán)限存入sem_perm.mode中; sem_otime被設(shè)置為0,sem_ctime被置為當(dāng)前時(shí)間; sem_nsems被置為nsems參數(shù)的值; 與該集合中每個(gè)信號(hào)燈關(guān)聯(lián)的各個(gè)sem結(jié)構(gòu)并不初始化。這些結(jié)構(gòu)必須是在以SETVAL或SETALL命令調(diào)用semctl時(shí)初始化的。Linux 培培訓(xùn)訓(xùn)信號(hào)量創(chuàng)建問(wèn)題lSystemV信號(hào)燈的創(chuàng)建和初始化需兩次函數(shù)調(diào)用是一個(gè)致命的缺陷,這會(huì)導(dǎo)致競(jìng)爭(zhēng)狀態(tài)的出現(xiàn)。l解決競(jìng)爭(zhēng)狀態(tài)的方法是:當(dāng)semget創(chuàng)建一個(gè)新的信號(hào)燈集時(shí),其semid_ds結(jié)構(gòu)的sem_otime成員保證被設(shè)置為0。該成員只是在semop調(diào)用成功
28、時(shí)才被設(shè)置為當(dāng)前值。在調(diào)用semget進(jìn)行訪問(wèn)而不是創(chuàng)建時(shí),以IPC_STAT命令調(diào)用semctl,然后等待sem_otime變?yōu)榉橇阒?。到時(shí)就可斷定該信號(hào)燈已經(jīng)被初始化,而且對(duì)它初始化的進(jìn)程已成功完成semop調(diào)用。所以,創(chuàng)建該信號(hào)燈集的進(jìn)程必須初始化它的值,而且必須在任何其他進(jìn)程可以使用該信號(hào)燈集之前調(diào)用semop。l這樣將會(huì)造成程序相當(dāng)復(fù)雜Linux 培培訓(xùn)訓(xùn)semop函數(shù) l#include lint semop(int semid, struct sembuf *opsptr, size_t nops);l返回:成功時(shí)為0,出錯(cuò)時(shí)為-1l對(duì)一個(gè)或多個(gè)信號(hào)燈進(jìn)行操作。lopsptr指向
29、如下結(jié)構(gòu)模板的數(shù)組(該結(jié)構(gòu)可能不止如下幾個(gè)成員):struct sembuf shrot sem_num; /* semaphore number:0,1,.,nsems-1 */ short sem_op; /* semaphore operation: 0 */ short sem_flg; /* operation flags:0,IPC_NOWAIT,SEM_UNDO */;lnops參數(shù)指出結(jié)構(gòu)數(shù)組中元素的個(gè)數(shù)。每個(gè)元素給目標(biāo)信號(hào)燈集中某個(gè)信號(hào)燈指定一個(gè)操作。特定的信號(hào)燈由sem_num指定;sem_op指定特定的操作;sem_flg指定非阻塞(IPC_NOWAIT)、恢復(fù)等標(biāo)志。在
30、阻塞、非阻塞情況下返回的錯(cuò)誤情況與其他SystemV IPC相同。lsemop函數(shù)由內(nèi)核保證原子的執(zhí)行,內(nèi)核或者完成所有操作,或者什么也不做。lsemop操作的具體描述:如果sem_op是正數(shù),其值就加到semval(信號(hào)燈的當(dāng)前值)上,這對(duì)應(yīng)于釋放由某個(gè)信號(hào)燈控制的資源。如果指定了SEM_UNDO標(biāo)志,就從相應(yīng)信號(hào)燈的semadj值中減掉sem_op的值。 如果sem_op是0,那么調(diào)用者希望等待到semval變?yōu)?,如果semval已經(jīng)是0,則立即返回;如果semval不為0,相應(yīng)信號(hào)燈的semzcnt(等待semval變?yōu)?的線程數(shù))值就加1,調(diào)用線程阻塞到semval變?yōu)?(那時(shí)sem
31、zcnt再減1)。若指定了IPC_NOWAIT,則調(diào)用線程不會(huì)睡眠,返回EAGAIN。 如果sem_op是負(fù)數(shù),那么調(diào)用者希望等待semval變?yōu)榇笥诨虻扔趕em_op的絕對(duì)值,這對(duì)應(yīng)于分配資源。如果semval大于或等于sem_op的絕對(duì)值,則從semval中減掉sem_op的絕對(duì)值,如果指定了SEM_UNDO,那么sem_op的絕對(duì)值就加到相應(yīng)信號(hào)燈的semadj值上。如果semval小于sem_op的絕對(duì)值,相應(yīng)信號(hào)燈的semncnt值就加1,調(diào)用線程阻塞直到semval變?yōu)榇笥诨虻扔趕em_op的絕對(duì)值。若指定了IPC_NOWAIT,則調(diào)用線程不會(huì)睡眠,返回EAGAIN。 lsemad
32、j稱(chēng)為指定信號(hào)燈針對(duì)調(diào)用進(jìn)程的調(diào)整值。當(dāng)調(diào)用進(jìn)程終止時(shí),semadj的值就加到相應(yīng)信號(hào)燈的semval上。若調(diào)用進(jìn)程對(duì)某個(gè)信號(hào)燈的全部操作都指定SEM_UNDO標(biāo)志,則該進(jìn)程終止時(shí),該信號(hào)燈的值就會(huì)變得像根本沒(méi)有運(yùn)行過(guò)該進(jìn)程一樣,這就是復(fù)舊(undo)的本意。Linux 培培訓(xùn)訓(xùn)semop的調(diào)用問(wèn)題lsemop采用復(fù)雜的信號(hào)燈集做參數(shù),因此造成程序調(diào)用變得復(fù)雜.l信號(hào)燈的值加1,或值減1都在semop完成,相當(dāng)于加鎖或解鎖都是有一個(gè)函數(shù)完成,這也是與其它互質(zhì)量等其它同步機(jī)制不一樣的地方l一般是將其封裝成P,V原語(yǔ)的函數(shù)來(lái)操作/* 申請(qǐng)資源,用P原語(yǔ)*/int semaphore_wait_p(
33、int sem_id) struct sembuf sb;sb.sem_num = 0;sb.sem_op = -1;sb.sem_flg = SEM_UNDO;if (semop(sem_id, &sb, 1) = -1) fprintf(stderr, semaphore_p failedn);return (-1);return 0;/* 釋放或分配資源用,用V原語(yǔ) */int semaphore_signal_v(int sem_id) struct sembuf sb;sb.sem_num = 0;sb.sem_op = 1;sb.sem_flg = SEM_UNDO;if
34、(semop(sem_id, &sb, 1) = -1) fprintf(stderr, semaphore_v failedn);return (-1);return 0;Linux 培培訓(xùn)訓(xùn)semctl函數(shù) l#include lint semctl(int semid, int semnum, int cmd, /* union arg */);l返回:成功時(shí)為非負(fù)值,出錯(cuò)時(shí)為-1l對(duì)一個(gè)信號(hào)燈執(zhí)行各種控制操作。lsemnum標(biāo)識(shí)某個(gè)信號(hào)燈,semnum僅僅用于GETVAL、SETVAL、GETNCNT、GETZCNT和GETPID命令。l第四個(gè)參數(shù)是可選的,它依賴(lài)于第三個(gè)參數(shù)c
35、md。它是一個(gè)聯(lián)合:union semun int val; /* used for SETVAL only */ struct semid_ds *buf; /* used fro IPC_SET and IPC_STAT */ ushort *array; /* used for GETALL and SETALL */;l該聯(lián)合沒(méi)有出現(xiàn)在任何系統(tǒng)頭文件中,由應(yīng)用程序聲明。而且它是以值傳遞的,而不是以引用傳遞的。Linux 培培訓(xùn)訓(xùn)semop命令選項(xiàng)lGETVAL:把semval的當(dāng)前值作為函數(shù)返回值返回。 lSETVAL:把semval設(shè)置為arg.val。如果操作成功,那么相應(yīng)信號(hào)燈在
36、所在進(jìn)程中的調(diào)整值(semadj)將被置為0。 lGETPID:把sempid的當(dāng)前值作為函數(shù)值返回。 lGETNCNT:把semncnt的當(dāng)前值作為函數(shù)值返回。 lGETZCNT:把semzcnt的當(dāng)前值作為函數(shù)值返回。 lGETALL:返回所指定信號(hào)燈集的每個(gè)成員的semval值。這些值通過(guò)arg.array指針?lè)祷?。函?shù)本身返回值為0。注意,調(diào)用者必須分配足夠容納所指定信號(hào)燈集中所有成員的semval值的一個(gè)unsigned short整數(shù)數(shù)組,然后把a(bǔ)rg.array設(shè)置成指向這個(gè)數(shù)組。 lSETALL:設(shè)置所指定信號(hào)燈集中每個(gè)成員的semval值。這些值通過(guò)arg.array數(shù)組指定
37、。 lIPC_RMID:把由semid指定的信號(hào)燈集從系統(tǒng)中刪除。 lIPC_SET:設(shè)置semid_ds結(jié)構(gòu)中的以下三個(gè)成員:sem_perm.uid、sem_perm.gid和sem_perm.mode。這些值來(lái)自由arg.buf參數(shù)指向的結(jié)構(gòu)中相應(yīng)成員。semid_ds中的sem_ctime成員也被設(shè)置為當(dāng)前值。 lIPC_STAT:通過(guò)arg.buf參數(shù)返回當(dāng)前的semid_ds結(jié)構(gòu)。注意,調(diào)用者必須首先分配一個(gè)semid_ds結(jié)構(gòu),并把a(bǔ)rg.buf設(shè)置為指向這個(gè)結(jié)構(gòu)。Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux
38、 培培訓(xùn)訓(xùn)共享內(nèi)存數(shù)據(jù)表示l對(duì)于每個(gè)System V共享內(nèi)存區(qū),內(nèi)核維護(hù)如下的信息結(jié)構(gòu):struct shmid_ds struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ pid_t shm_lpid; /* pid of last shmop */ pid_t shm_cpid; /* pid of creator */ shmatt_t shm_nattch; /* current # attached */ shmat_t
39、shm_cnattch; /* in-core # attached */ time_t shm_atime; /* last shmat time */ time_t shm_dtime; /* last shmdt time */ time_t shm_ctime; /* last change time */;Linux 培培訓(xùn)訓(xùn)System V 共享內(nèi)存使用流程l使用頭文件#include #include lshmget() 獲得共享內(nèi)存區(qū)域的ID 如果不存在指定的共享區(qū)域就創(chuàng)建相應(yīng)的區(qū)域。 int shmget(key_t key,int size,int shmflg); lsh
40、mat()把共享內(nèi)存區(qū)域映射到調(diào)用進(jìn)程的地址空間中去 這樣,進(jìn)程就可以方便地對(duì)共享區(qū)域進(jìn)行訪問(wèn)操作。void *shmat(int shmid,const void *shmaddr,int shmflg); lshmdt()調(diào)用用來(lái)解除進(jìn)程對(duì)共享內(nèi)存區(qū)域的映射 int shmdt(const void *shmaddr); lShmctl()實(shí)現(xiàn)對(duì)共享內(nèi)存區(qū)域的控制操作 int shmctl(int shmid,int cmd,struct shmid_ds *buf); Linux 培培訓(xùn)訓(xùn)shmget函數(shù) l#include lint shmget(key_t key, size_t s
41、ize, int oflag);l返回:成功時(shí)為共享內(nèi)存區(qū)對(duì)象,出錯(cuò)時(shí)為-1l函數(shù)創(chuàng)建一個(gè)尚未存在的共享內(nèi)存區(qū),或者訪問(wèn)一個(gè)已存在的共享內(nèi)存區(qū)。l返回值是共享內(nèi)存區(qū)標(biāo)識(shí)符,供其他函數(shù)使用。lsize參數(shù)以字節(jié)為單位指定內(nèi)存的大小。當(dāng)實(shí)際操作為創(chuàng)建一個(gè)新的內(nèi)存區(qū)時(shí),必須指定一個(gè)不為0的size值;如果實(shí)際操作是訪問(wèn)一個(gè)已存在的共享內(nèi)存區(qū),則size應(yīng)為0。l當(dāng)實(shí)際操作為創(chuàng)建一個(gè)新的內(nèi)存區(qū)時(shí),該內(nèi)存區(qū)被初始化為size個(gè)字節(jié)的0。Linux 培培訓(xùn)訓(xùn)shmat函數(shù) l#include lvoid * shmat(int shmid, const void *shmaddr, int flag);l
42、返回:成功時(shí)為映射區(qū)的其始地址,出錯(cuò)時(shí)為-1l調(diào)用shmat將共享內(nèi)存區(qū)附接到調(diào)用進(jìn)程的地址空間。lshmid是shmget的返回值。shmat的返回值是所指定的共享內(nèi)存區(qū)在調(diào)用進(jìn)程內(nèi)的起始地址。確定此地址的規(guī)則如下:如果shmaddr是空指針,則系統(tǒng)替調(diào)用者選擇地址。這是推薦(也是可移植性最好的)方法。 如果shmaddr非空,則返回地址取決于調(diào)用者是否給flag參數(shù)指定了SHM_RND值。如果SHM_RND沒(méi)有指定,則共享內(nèi)存區(qū)附接到由shmaddr指定的地址;若指定SHM_RND,則附接到由shmaddr指定的地址向下舍入一個(gè)SHMLBA常值。LBA代表“低端邊界地址(lower bou
43、ndary address)”。 lflag參數(shù)可以指定SHM_RDONLY值,它限定只讀訪問(wèn)。Linux 培培訓(xùn)訓(xùn)shmdt函數(shù) l#include lint shmdt(const void *shmaddr);l返回:成功時(shí)為0,出錯(cuò)時(shí)為-1l調(diào)用shmdt斷開(kāi)與共享內(nèi)存區(qū)的連接。l當(dāng)一個(gè)進(jìn)程終止時(shí),它的所有當(dāng)前附接著的共享內(nèi)存區(qū)都自動(dòng)斷接掉。Linux 培培訓(xùn)訓(xùn)shmctl函數(shù) l#include lint shmctl(int shmid, int cmd, struct shmid_ds *buff);l返回:成功時(shí)為0,出錯(cuò)時(shí)為-1l函數(shù)提供三個(gè)命令:IPC_RMID:從系統(tǒng)中刪
44、除由shmid標(biāo)識(shí)的共享內(nèi)存區(qū)并拆除它。 IPC_SET:給所指定的共享內(nèi)存區(qū)設(shè)置其shmid_ds結(jié)構(gòu)的以下三個(gè)成員:shm_perm.uid、shm_perm.gid和shm_perm.mode,它們的值來(lái)自參數(shù)中的相應(yīng)成員。shm_ctime的值用當(dāng)前時(shí)間替換。 IPC_STAT:向調(diào)用者返回所指定共享內(nèi)存區(qū)的當(dāng)前shmid_ds結(jié)構(gòu)。 Linux 培培訓(xùn)訓(xùn)關(guān)于System V的維護(hù)命令l可以用ipcs命令查看system V對(duì)象l用ipcrm可以刪除system V 對(duì)象ipcrm sem 196632 l刪除semid 為196632的信號(hào)量ipcrm shm 12395l刪除shm
45、id 為12395的共享內(nèi)存ipcrm msg 234l刪除msgid為 234的消息隊(duì)列Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)兩大類(lèi)應(yīng)用接口區(qū)別lSystem V IPC存在時(shí)間比較老,許多系統(tǒng)都支持,而Posix IPC是新出的標(biāo)準(zhǔn).很多嵌入式平臺(tái)只支持System V 的接口lSystem V的接口相對(duì)復(fù)雜,而POSIX比較簡(jiǎn)單,優(yōu)先選擇后者.參見(jiàn)system V的信號(hào)量和Posix信號(hào)量的操作比較lPOSIX IPC是線程安全的lSystem V內(nèi)置在glibc中,因此所有使用glibc庫(kù)的環(huán)境都可
46、以使用,POSIX IPC的使用必須鏈接librt.XXX庫(kù),(即使用-lrt參數(shù))Linux 培培訓(xùn)訓(xùn)POSIX 消息隊(duì)列接口名稱(chēng)接口名稱(chēng)目的目的mq_open(3RT) 連接到以及創(chuàng)建(可選)命名消息隊(duì)列連接到以及創(chuàng)建(可選)命名消息隊(duì)列mq_close(3RT) 結(jié)束到開(kāi)放式消息隊(duì)列的連接結(jié)束到開(kāi)放式消息隊(duì)列的連接mq_unlink(3RT) 結(jié)束到開(kāi)放式消息隊(duì)列的連接,并在最后一個(gè)進(jìn)程關(guān)閉此隊(duì)結(jié)束到開(kāi)放式消息隊(duì)列的連接,并在最后一個(gè)進(jìn)程關(guān)閉此隊(duì)列時(shí)將其刪除列時(shí)將其刪除mq_send(3RT) 將消息放入隊(duì)列將消息放入隊(duì)列mq_receive(3RT) 在隊(duì)列中接收(刪除)最早且優(yōu)先級(jí)最
47、高的消息在隊(duì)列中接收(刪除)最早且優(yōu)先級(jí)最高的消息mq_notify(3RT) 通知進(jìn)程或線程消息已存在于隊(duì)列中通知進(jìn)程或線程消息已存在于隊(duì)列中mq_setattr(3RT), mq_getattr(3RT) 設(shè)置或獲取消息隊(duì)列屬性設(shè)置或獲取消息隊(duì)列屬性Linux 培培訓(xùn)訓(xùn)POSIX消息隊(duì)列使用l使用頭文件使用頭文件mqueue.hl隊(duì)列數(shù)據(jù)結(jié)構(gòu)隊(duì)列數(shù)據(jù)結(jié)構(gòu) mqd_tl打開(kāi)隊(duì)列打開(kāi)隊(duì)列mqd_t mq_open(const char *name, int oflag, /* unsigned long mode, mq_attr attr */ .); l關(guān)閉隊(duì)列關(guān)閉隊(duì)列Linux 培培訓(xùn)訓(xùn)
48、POSIX 信號(hào)量 lPosix信號(hào)量的使用遠(yuǎn)比System V信號(hào)量簡(jiǎn)單.而且支持多種操作系統(tǒng).lsem_open(3RT) 連接到以及創(chuàng)建(可選)命名信號(hào)量連接到以及創(chuàng)建(可選)命名信號(hào)量lsem_init(3RT) 初始化信號(hào)量結(jié)構(gòu)(在調(diào)用程序內(nèi)部,因此不是命名信號(hào)量)初始化信號(hào)量結(jié)構(gòu)(在調(diào)用程序內(nèi)部,因此不是命名信號(hào)量)lsem_close(3RT) 結(jié)束到打開(kāi)信號(hào)量的連接結(jié)束到打開(kāi)信號(hào)量的連接lsem_unlink(3RT) 結(jié)束到打開(kāi)信號(hào)量的連接,并在最后一個(gè)進(jìn)程關(guān)閉此信號(hào)量時(shí)將其刪除結(jié)束到打開(kāi)信號(hào)量的連接,并在最后一個(gè)進(jìn)程關(guān)閉此信號(hào)量時(shí)將其刪除lsem_destroy(3RT)
49、銷(xiāo)毀信號(hào)量結(jié)構(gòu)(在調(diào)用程序內(nèi)部,因此不是命名信號(hào)量)銷(xiāo)毀信號(hào)量結(jié)構(gòu)(在調(diào)用程序內(nèi)部,因此不是命名信號(hào)量)lsem_getvalue(3RT) 將信號(hào)量的值復(fù)制到指定整數(shù)中將信號(hào)量的值復(fù)制到指定整數(shù)中l(wèi)sem_wait(3RT)、sem_trywait(3RT) 當(dāng)其他進(jìn)程擁有信號(hào)量時(shí)進(jìn)行阻塞,或者當(dāng)其他進(jìn)程擁有信號(hào)量時(shí)返回錯(cuò)誤當(dāng)其他進(jìn)程擁有信號(hào)量時(shí)進(jìn)行阻塞,或者當(dāng)其他進(jìn)程擁有信號(hào)量時(shí)返回錯(cuò)誤lsem_post(3RT) 遞增信號(hào)量計(jì)數(shù)遞增信號(hào)量計(jì)數(shù)Company nameLinux培培訓(xùn)訓(xùn)主講人:主講人:肖勇軍肖勇軍桂電嵌入式交流群:156619189Linux 培培訓(xùn)訓(xùn)共享內(nèi)存l共享內(nèi)存可以
50、說(shuō)是最有用的進(jìn)程間通信方式,也是最快的IPC形式。兩個(gè)不同進(jìn)程A、B共享內(nèi)存的意思是,同一塊物理內(nèi)存被映射到進(jìn)程A、B各自的進(jìn)程地址空間。進(jìn)程A可以即時(shí)看到進(jìn)程B對(duì)共享內(nèi)存中數(shù)據(jù)的更新,反之亦然。l由于多個(gè)進(jìn)程共享同一塊內(nèi)存區(qū)域,必然需要某種同步機(jī)制,互斥鎖和信號(hào)量都可以。l共享內(nèi)存通信的一個(gè)顯而易見(jiàn)的好處是效率高,因?yàn)檫M(jìn)程可以直接讀寫(xiě)內(nèi)存,而不需要任何數(shù)據(jù)的拷貝。對(duì)于像管道和消息隊(duì)列等通信方式,則需要在內(nèi)核和用戶(hù)空間進(jìn)行四次的數(shù)據(jù)拷貝,而共享內(nèi)存則只拷貝兩次數(shù)據(jù)1:一次從輸入文件到共享內(nèi)存區(qū),另一次從共享內(nèi)存區(qū)到輸出文件。 l共享內(nèi)存廣泛被應(yīng)用數(shù)據(jù)庫(kù)系統(tǒng)實(shí)現(xiàn)到驅(qū)動(dòng)程序各種應(yīng)用 Linux 培
51、培訓(xùn)訓(xùn)共享內(nèi)存的實(shí)現(xiàn)lLinux有三種共享內(nèi)存實(shí)現(xiàn)機(jī)制mmap()System V 共享內(nèi)存Posix 共享內(nèi)存前兩者較為常用l系統(tǒng)調(diào)用mmap()通過(guò)映射一個(gè)普通文件實(shí)現(xiàn)共享內(nèi)存。系統(tǒng)V則是通過(guò)映射特殊文件系統(tǒng)shm中的文件實(shí)現(xiàn)進(jìn)程間的共享內(nèi)存通信。也就是說(shuō),每個(gè)共享內(nèi)存區(qū)域?qū)?yīng)特殊文件系統(tǒng)shm中的一個(gè)文件(這是通過(guò)shmid_kernel結(jié)構(gòu)聯(lián)系起來(lái)的)Linux 培培訓(xùn)訓(xùn)mmaplmmap函數(shù)把一個(gè)文件或一個(gè)Posix共享內(nèi)存區(qū)對(duì)象映射到調(diào)用進(jìn)程的地址空間。使用該函數(shù)有三個(gè)目的: 1.使用普通文件以提供內(nèi)存映射I/O 2.使用特殊文件以提供匿名內(nèi)存映射。 3.使用shm_open以提供
52、無(wú)親緣關(guān)系進(jìn)程間的Posix共享內(nèi)存區(qū) Linux 培培訓(xùn)訓(xùn)mmap-創(chuàng)建一個(gè)共享內(nèi)存區(qū)名稱(chēng)::mmap功能:把I/O文件映射到一個(gè)存儲(chǔ)區(qū)域中頭文件:#include 函數(shù)原形:void *mmap(void *addr,size_t len,int prot,int flag,int filedes,off_t off);參數(shù):addr 指向映射存儲(chǔ)區(qū)的起始地址,addr參數(shù)用于指定映射存儲(chǔ)區(qū)的起始地址。通常將其設(shè)置為NULL,這表示由系統(tǒng)選擇該映射區(qū)的起始地址。len 映射的字節(jié)prot 對(duì)映射存儲(chǔ)區(qū)的保護(hù)要求flag flag標(biāo)志位filedes 要被映射文件的描述符, 在映射該文件到一
53、個(gè)地址空間之前,先要打開(kāi)該文件。len是映射的字節(jié)數(shù)。off 要映射字節(jié)在文件中的起始偏移量,通常將其設(shè)置為0。 返回值:若成功則返回映射區(qū)的起始地址,若出錯(cuò)則返回MAP_FAILEDLinux 培培訓(xùn)訓(xùn)mmap參數(shù)說(shuō)明l prot參數(shù)說(shuō)明對(duì)映射存儲(chǔ)區(qū)的保護(hù)要求??蓪rot參數(shù)指定為PROT_NONE,或者是PROT_READ(映射區(qū)可讀),PROT_WRITE(映射區(qū)可寫(xiě)),PROT_EXEC(映射區(qū)可執(zhí)行)任意組合的按位或,也可以是PROT_NONE(映射區(qū)不可訪問(wèn))。對(duì)指定映射存儲(chǔ)區(qū)的保護(hù)要求不能超過(guò)文件open模式訪問(wèn)權(quán)限。 l flag參數(shù)影響映射區(qū)的多種屬性: MAP_FIXED
54、 返回值必須等于addr.因?yàn)檫@不利于可移植性,所以不鼓勵(lì)使用此標(biāo)志。MAP_SHARED 這一標(biāo)志說(shuō)明了本進(jìn)程對(duì)映射區(qū)所進(jìn)行的存儲(chǔ)操作的配置。此標(biāo)志指定存儲(chǔ)操作修改映射文件。MAP_PRIVATE 本標(biāo)志導(dǎo)致對(duì)映射區(qū)建立一個(gè)該映射文件的一個(gè)私有副本。所有后來(lái)對(duì)該映射區(qū)的引用都是引用該副本,而不是原始文件。要注意的是必須指定MAP_FIXED或MAP_PRIVATE標(biāo)志其中的一個(gè),指定前者是對(duì)存儲(chǔ)映射文件本身的一個(gè)操作,而后者是對(duì)其副本進(jìn)行操作。Linux 培培訓(xùn)訓(xùn)unmmap取消一個(gè)共享內(nèi)存名稱(chēng)::munmap功能:解除存儲(chǔ)映射頭文件:#include 函數(shù)原形:int munmap(cad
55、dr_t addr,size_t len);參數(shù):addr 指向映射存儲(chǔ)區(qū)的起始地址,其中addr參數(shù)是由mmap返回的地址 ,len 映射的尺寸。再次訪問(wèn)這些地址導(dǎo)致向調(diào)用進(jìn)程產(chǎn)生一個(gè)SIGSEGV信號(hào)。 返回值:若成功則返回0,若出錯(cuò)則返回-1Linux 培培訓(xùn)訓(xùn)名稱(chēng)::msync功能:同步文件到存儲(chǔ)器頭文件:#include 函數(shù)原形:int msync(void *addr,size_t len,int flags);參數(shù):addr 指向映射存儲(chǔ)區(qū)的起始地址len 映射的字節(jié)prot flags返回值:若成功則返回0,若出錯(cuò)則返回-1Linux 培培訓(xùn)訓(xùn)posix共享內(nèi)存lposix共
56、享內(nèi)存區(qū)涉及兩個(gè)步驟:1、指定一個(gè)名字參數(shù)調(diào)用shm_open,以創(chuàng)建一個(gè)新的共享內(nèi)存區(qū)對(duì)象或打開(kāi)一個(gè)以存在的共享內(nèi)存區(qū)對(duì)象。2、調(diào)用mmap把這個(gè)共享內(nèi)存區(qū)映射到調(diào)用進(jìn)程的地址空間。傳遞給shm_open的名字參數(shù)隨后由希望共享該內(nèi)存區(qū)的任何其他進(jìn)程使用。Linux 培培訓(xùn)訓(xùn)shm_open打開(kāi)共享內(nèi)存名稱(chēng)::shm_open功能:打開(kāi)或創(chuàng)建一個(gè)共享內(nèi)存區(qū)頭文件:#include 函數(shù)原形:int shm_open(const char *name,int oflag,mode_t mode);參數(shù):name 共享內(nèi)存區(qū)的名字cflag 標(biāo)志位, oflag參數(shù)必須含有O_RDONLY和O_RDWR標(biāo)志,還可以指定如下標(biāo)志:O_CREAT,O_EXCL或O_TRUNC. mode 權(quán)限
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 勤奮啟航青春不悔
- 教育行業(yè)在線教育質(zhì)量提升與教學(xué)改革方案
- 2025年三門(mén)峽駕??荚囏涍\(yùn)從業(yè)資格證考試
- 自然奇觀探索之旅讀后感
- 員工培訓(xùn)與發(fā)展培訓(xùn)活動(dòng)方案
- 2025年赤峰駕??荚囏涍\(yùn)從業(yè)資格證考試題庫(kù)
- 2025年長(zhǎng)沙貨運(yùn)從業(yè)資格證模擬考試0題題庫(kù)
- 勇攀高峰青春正好
- 互聯(lián)網(wǎng)行業(yè)個(gè)人信息保護(hù)免責(zé)聲明
- 智能回收系統(tǒng)開(kāi)發(fā)合同
- 電廠鍋爐爐膛煙道內(nèi)部作業(yè)三措兩案
- 收費(fèi)站(所)事故隱患排查清單
- 駕駛證學(xué)法減分(學(xué)法免分)題庫(kù)及答案(200題完整版)
- 四川省宜賓市敘州區(qū)2023-2024學(xué)年七年級(jí)上學(xué)期期末數(shù)學(xué)試題(含答案)
- 高績(jī)效教練的讀書(shū)心得分享
- 論同性婚姻是否應(yīng)該合法化問(wèn)題
- 軟管出廠檢測(cè)報(bào)告
- 修路方案預(yù)案
- 公司業(yè)務(wù)流程與工作流程介紹
- 產(chǎn)業(yè)經(jīng)濟(jì)學(xué)-第八章-產(chǎn)業(yè)關(guān)聯(lián)
- 華東政法大學(xué)2017-2018學(xué)年期末測(cè)試《國(guó)際法》試卷
評(píng)論
0/150
提交評(píng)論