日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入探究Linuxmmap的實(shí)現(xiàn)方式(linuxmmap實(shí)現(xiàn))

在Linux系統(tǒng)中,mmap是一種常用的內(nèi)存映射方式。通過mmap,可以將一個文件或者一個設(shè)備映射到進(jìn)程的地址空間,使得進(jìn)程可以像訪問普通內(nèi)存一樣訪問文件或設(shè)備。mmap方法的實(shí)現(xiàn)方式十分復(fù)雜,本文將從實(shí)現(xiàn)角度。

公司專注于為企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作、微信公眾號開發(fā)、商城網(wǎng)站定制開發(fā),成都小程序開發(fā),軟件按需開發(fā)網(wǎng)站等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。憑借多年豐富的經(jīng)驗(yàn),我們會仔細(xì)了解各客戶的需求而做出多方面的分析、設(shè)計(jì)、整合,為客戶設(shè)計(jì)出具風(fēng)格及創(chuàng)意性的商業(yè)解決方案,創(chuàng)新互聯(lián)更提供一系列網(wǎng)站制作和網(wǎng)站推廣的服務(wù)。

一、Linux mmap的基本概念

mmap是Linux內(nèi)核提供的一種I/O操作接口,可以將文件或設(shè)備映射到進(jìn)程的地址空間,使得進(jìn)程可以像訪問普通內(nèi)存一樣訪問文件或設(shè)備。mmap可以將一個文件或設(shè)備的整個實(shí)體映射到地址空間,也可以根據(jù)需要進(jìn)行部分映射。mmap一般用于需要頻繁訪問文件或設(shè)備的應(yīng)用程序,可以大大提高I/O性能。

mmap主要通過vma(Virtual Memory Area)描述地址空間中的映射區(qū)域。vma結(jié)構(gòu)體包括映射區(qū)域的起始地址、大小、訪問權(quán)限、映射的對象(文件或設(shè)備)等信息。在Linux系統(tǒng)中,每個進(jìn)程都有自己的地址空間,由多個vma描述。

二、Linux mmap的實(shí)現(xiàn)方式

Linux mmap的實(shí)現(xiàn)方式十分復(fù)雜,下面將詳細(xì)介紹Linux mmap的實(shí)現(xiàn)原理。

1. mmap系統(tǒng)調(diào)用的實(shí)現(xiàn)

在用戶進(jìn)程調(diào)用mmap系統(tǒng)調(diào)用時,Linux內(nèi)核會調(diào)用sys_mmap函數(shù)。sys_mmap函數(shù)首先對參數(shù)進(jìn)行檢查,然后調(diào)用do_mmap函數(shù)實(shí)現(xiàn)具體的映射操作。

do_mmap的實(shí)現(xiàn)過程如下:

(1)調(diào)用vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)函數(shù)找到當(dāng)前進(jìn)程地址空間中addr處的vma。

(2)判斷當(dāng)前的vma是否與要映射的地址重疊,如果重疊則返回錯誤。

(3)調(diào)用get_unmapped_area函數(shù)找到當(dāng)前進(jìn)程地址空間中一段未映射的區(qū)域。

(4)調(diào)用vm_area_struct *vm_area_alloc(struct mm_struct *mm)函數(shù)為新的vma分配一塊地址空間,將映射信息存儲到vma結(jié)構(gòu)體中。

(5)調(diào)用do_mmap_pgoff函數(shù)實(shí)現(xiàn)將文件映射到地址空間中,具體實(shí)現(xiàn)會在下面介紹。

2. 文件的映射

在調(diào)用do_mmap_pgoff函數(shù)時,首先需要根據(jù)文件的inode號在內(nèi)存中建立與文件對應(yīng)的頁表項(xiàng)(Page Table Entries,PTE)。Linux內(nèi)核中的PTE有兩種類型:軟件PTE和硬件PTE。軟件PTE由內(nèi)核管理,記錄一個vma所映射的虛擬地址和實(shí)際物理地址之間的映射關(guān)系。硬件PTE由CPU的內(nèi)存管理單元(Memory Management Unit,MMU)管理,記錄一個進(jìn)程虛擬地址和實(shí)際物理地址之間的映射關(guān)系。

建立好PTE后,就可以將文件內(nèi)容映射到進(jìn)程的地址空間中。具體步驟如下:

(1)調(diào)用file->f_op->mmap函數(shù)獲取文件的頁表(Page Table)。

(2)在vma結(jié)構(gòu)體中尋找相應(yīng)的PTE記錄,如果找到了,則表示之前已經(jīng)將文件的部分或者全部內(nèi)容映射到該進(jìn)程的地址空間中。

(3)如果沒有找到相應(yīng)的PTE記錄,則需要創(chuàng)建一個新的PTE,將文件內(nèi)容映射到相應(yīng)的虛擬地址中。

(4)通過vm_insert_page函數(shù)將新的PTE插入到進(jìn)程的頁表中。

(5)通過page_cache_release函數(shù)釋放文件的緩存。

映射完成后,Linux內(nèi)核會根據(jù)vma的屬性設(shè)置相應(yīng)的屬性,比如可讀可寫可執(zhí)行等。

3. 延遲映射

在Linux系統(tǒng)中,為了提高頁表的訪問效率,采用了一種稱為延遲映射(Lazy Mapping)的策略。延遲映射指的是在訪問一個虛擬地址時,才會真正將相應(yīng)的內(nèi)存頁映射到物理內(nèi)存上,而不是在mmap時就將整個文件映射到物理內(nèi)存中。

延遲映射的優(yōu)點(diǎn)在于可以大大減少內(nèi)存的消耗,因?yàn)椴皇撬械奈募急活l繁訪問,對于那些不常訪問的文件,延遲映射可以將其在內(nèi)存中定位但不占用實(shí)際內(nèi)存。

4. 文件頁管理

在Linux系統(tǒng)中,為了避免頻繁訪問磁盤,會針對常用的文件頁面緩存。

常用的方法是,調(diào)用算法來實(shí)現(xiàn)文件頁的管理。最常見的算法是LRU(Least Recently Used)算法,即最近最少使用算法,根據(jù)頁表項(xiàng)的最近使用時間來判斷哪些頁應(yīng)該被淘汰。其他的算法包括FIFO(First In First Out)、LFU(Least Frequently Used)等。

五、

本文詳細(xì)介紹了Linux mmap的實(shí)現(xiàn)方式。mmap的實(shí)現(xiàn)涉及到面向?qū)ο缶幊獭?nèi)存管理、硬件特性等多方面的知識。掌握Linux mmap的實(shí)現(xiàn)方式對于Linux系統(tǒng)的內(nèi)核開發(fā)和應(yīng)用開發(fā)都非常重要。

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù)!

linux共享內(nèi)存和mmap的區(qū)別

mmap的機(jī)制如:就是在磁盤上建立一個文件,每個進(jìn)程存儲器里面,單獨(dú)開辟一個空陸升間來進(jìn)行映射。如果多進(jìn)程的話,那么不會對實(shí)際的磨悉耐物理存儲器(主存)消耗太大。

shm的機(jī)制:每個進(jìn)程的共享內(nèi)存都直接映射到實(shí)際物理存儲器里面。

1、mmap保存到實(shí)際硬盤,實(shí)瞎春際存儲并沒有反映到主存上

2、shm保存到物理存儲器(主存),實(shí)際的儲存量直接反映到主存上。

使用上看:如果分配的存儲量不大,那么使用shm;如果存儲量大,那么使用shm。

以上內(nèi)容來源,

  共享內(nèi)存的創(chuàng)建

  根據(jù)理論:

  1. 共享內(nèi)存允許兩個或多個進(jìn)程共享一給定的存儲區(qū),因?yàn)閿?shù)據(jù)不需要來回復(fù)制,所以是最快的一種進(jìn)程間通信機(jī)制。共享內(nèi)存可以通過mmap()映射普通文件(特殊情況下還可以采用匿名映射)機(jī)制實(shí)現(xiàn),也可以通過系統(tǒng)V共享內(nèi)存機(jī)制實(shí)現(xiàn)。應(yīng)用接口和原理很簡單,內(nèi)部機(jī)制復(fù)雜。為了實(shí)現(xiàn)更安全通信,往往還與信號燈等同步機(jī)制共同使用。

  mmap的機(jī)制如:就是在磁盤上建立一個文件,每個進(jìn)程存儲器里面,單獨(dú)開辟一個空間來進(jìn)行映射。如果多進(jìn)程的話,那么不會對實(shí)際的物理存儲器(主存)消耗太大。

  shm的機(jī)制:每個進(jìn)程的共享內(nèi)存都直接映射到實(shí)際物理存儲器里面。

  結(jié)論:

  1、mmap保存到實(shí)際硬盤,實(shí)際存儲并沒有反映到主存上。優(yōu)點(diǎn):儲存量可以很大(多于主存)(這里一個問題,需要高手解答,會不會太多拷貝到主存里面???);缺點(diǎn):進(jìn)程間讀取和寫入速度要比主存的要慢。

  2、shm保存到物理存儲器(主存),實(shí)際的儲存量直接反映到主存上。優(yōu)點(diǎn),進(jìn)程間訪問速度(讀寫)比磁盤要快;缺點(diǎn),儲存量不能非常大(多于主存)

  使用上看:如果分配的存儲量不大,那么使用shm;如果存儲量大,那么使用shm。

  參看百度:

  mmap就是一個文件操作

  看這些百度的描述:

  mmap()系統(tǒng)調(diào)用使得進(jìn)程之間通過映射同一個普通文件實(shí)現(xiàn)共享內(nèi)存。普通文件被映射到進(jìn)程地址空間后,進(jìn)程可以向訪問普通內(nèi)存一樣對文件進(jìn)行訪問,不必再調(diào)用read(),write()等操作。 成功執(zhí)行時,mmap()返回被映射區(qū)的指針,munmap()返回0。失敗時,mmap()返回MAP_FAILED,munmap返回-1。errno被設(shè)為以下的某個值 EACCES:訪問出錯EAGAIN:文件已被鎖定,或者太多的內(nèi)存已被鎖定EBADF:fd不是有效的文件描述詞EINVAL:一個或者多個參數(shù)無效 ENFILE:已達(dá)到系統(tǒng)對打開文件的限制ENODEV:指定文件所在的文件系統(tǒng)不判團(tuán)支持內(nèi)存映射ENOMEM:內(nèi)存不足,或者進(jìn)程已超出更大內(nèi)存映射數(shù)量 EPERM:權(quán)能不足,操作不允許ETXTBSY:已寫的方式打開文件,同時指定MAP_DENYWRITE標(biāo)毀啟志SIGSEGV:試著向只讀區(qū)寫入 SIGBUS:試著訪問不屬于進(jìn)程的內(nèi)存區(qū)參數(shù)fd為即將映射到進(jìn)程空間的文件描述字,

  一般由open()返回,同時,fd可以指定為-1,此時須指定 flags參數(shù)中的MAP_ANON,表明進(jìn)行的是匿名映射(不涉及具體的文件名,避免了文件的創(chuàng)建及打開,很顯然只能用于具有親緣關(guān)系的進(jìn)程間通信)

  相關(guān)文章參考:

  mmap函數(shù)是unix/linux下的系統(tǒng)調(diào)用,來看《Unix Netword programming》卷二12.2節(jié)有詳細(xì)介紹。

  mmap系統(tǒng)調(diào)用并不是完全為了用于共享內(nèi)存而設(shè)計(jì)的。它本身提供了不同于一般對普通文件的訪問方式,進(jìn)程可以像讀寫內(nèi)存一樣對普通文纖沖如件的操作。而Posix或系統(tǒng)V的共享內(nèi)存IPC則純粹用于共享目的,當(dāng)然mmap()實(shí)現(xiàn)共享內(nèi)存也是其主要應(yīng)用之一。

  mmap系統(tǒng)調(diào)用使得進(jìn)程之間通過映射同一個普通文件實(shí)現(xiàn)共享內(nèi)存。普通文件被映射到進(jìn)程地址空間后,進(jìn)程可以像訪問普通內(nèi)存一樣對文件進(jìn)行訪問,不必再 調(diào)用read(),write()等操作。mmap并不分配空間, 只是將文件映射到調(diào)用進(jìn)程的地址空間里, 然后你就可以用memcpy等操作寫文件, 而不用write()了.寫完后用msync()同步一下, 你所寫的內(nèi)容就保存到文件里了. 不過這種方式?jīng)]辦法增加文件的長度, 因?yàn)橐成涞拈L度在調(diào)用mmap()的時候就決定了.

  簡單說就是把一個文件的內(nèi)容在內(nèi)存里面做一個映像,內(nèi)存比磁盤快些。

  基本上它是把一個檔案對應(yīng)到你的virtual memory 中的一段,并傳回一個指針。

  重寫總結(jié):

  1、mmap實(shí)際就是操作“文件”。

  2、映射文件,除了主存的考慮外。shm的內(nèi)存共享,效率應(yīng)該比mmap效率要高(mmap通過io和文件操作,或“需要寫完后用msync()同步一下”);當(dāng)然mmap映射操作文件,比直接操作文件要快些;由于多了一步msync應(yīng)該可以說比shm要慢了吧???

  3、另一方面,mmap的優(yōu)點(diǎn)是,操作比shm簡單(沒有調(diào)用比shm函數(shù)復(fù)雜),我想這也是許多人喜歡用的原因,包括nginx。

  缺點(diǎn),還得通過實(shí)際程序測試,確定?。?!

  

  修正理解(這也真是的,這個網(wǎng)站沒辦法附加;只能重寫了):

  今天又細(xì)心研究了一下,發(fā)現(xiàn)百度這么一段說明:

  2、系統(tǒng)調(diào)用mmap()用于共享內(nèi)存的兩種方式:

  (1)使用普通文件提供的內(nèi)存映射:適用于任何進(jìn)程之間;此時,需要打開或創(chuàng)建一個文件,然后再調(diào)用mmap();典型調(diào)用代碼如下:

  fd=open(name, flag, mode);

  if(fd

  …

  ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0); 通過mmap()實(shí)現(xiàn)共享內(nèi)存的通信方式有許多特點(diǎn)和要注意的地方,我們將在范例中進(jìn)行具體說明。

 ?。?)使用特殊文件提供匿名內(nèi)存映射:適用于具有親緣關(guān)系的進(jìn)程之間;由于父子進(jìn)程特殊的親緣關(guān)系,在父進(jìn)程中先調(diào)用mmap(),然后調(diào)用fork()。那么在調(diào)用fork()之后,子進(jìn)程繼承父進(jìn)程匿名映射后的地址空間,同樣也繼承mmap()返回的地址,這樣,父子進(jìn)程就可以通過映射區(qū)域進(jìn)行通信了。注意,這里不是一般的繼承關(guān)系。一般來說,子進(jìn)程單獨(dú)維護(hù)從父進(jìn)程繼承下來的一些變量。而mmap()返回的地址,卻由父子進(jìn)程共同維護(hù)。

  看了一下windows“內(nèi)存映射文件”:

  內(nèi)存映射文件與虛擬內(nèi)存有些類似,通過內(nèi)存映射文件可以保留一個地址空間的區(qū)域,同時將物理存儲器提交給此區(qū)域,只是內(nèi)存文件映射的物理存儲器來自一個已經(jīng)存在于磁盤上的文件,而非系統(tǒng)的頁文件,而且在對該文件進(jìn)行操作之前必須首先對文件進(jìn)行映射,就如同將整個文件從磁盤加載到內(nèi)存。由此可以看出,使用內(nèi)存映射文件處理存儲于磁盤上的文件時,將不必再對文件執(zhí)行I/O操作,這意味著在對文件進(jìn)行處理時將不必再為文件申請并分配緩存,所有的文件緩存操作均由系統(tǒng)直接管理,由于取消了將文件數(shù)據(jù)加載到內(nèi)存、數(shù)據(jù)從內(nèi)存到文件的回寫以及釋放內(nèi)存塊等步驟,使得內(nèi)存映射文件在處理大數(shù)據(jù)量的文件時能起到相當(dāng)重要的作用。另外,實(shí)際工程中的系統(tǒng)往往需要在多個進(jìn)程之間共享數(shù)據(jù),如果數(shù)據(jù)量小,處理方法是靈活多變的,如果共享數(shù)據(jù)容量巨大,那么就需要借助于內(nèi)存映射文件來進(jìn)行。實(shí)際上,內(nèi)存映射文件正是解決本地多個進(jìn)程間數(shù)據(jù)共享的最有效方法。

  

  這里再總結(jié)一次:

  1、mmap有兩種方式,一種是映射內(nèi)存,它把普通文件映射為實(shí)際物理內(nèi)存頁,訪問它就和訪問物理內(nèi)存一樣(這也就和shm的功能一樣了)(同時不用刷新到文件)

  2、mmap可以映射文件,不確定會不會像windows“內(nèi)存映射文件”一樣的功能,如果是,那么他就能映射好幾G甚至好幾百G的內(nèi)存數(shù)據(jù),對大數(shù)據(jù)處理將提供強(qiáng)大功能了???

  3、shm只做內(nèi)存映射,和mmap之一個功能一樣!只不過不是普通文件而已,但都是物理內(nèi)存。

共享內(nèi)存允許兩個或多個進(jìn)程共享一給定的存儲區(qū),因?yàn)閿?shù)據(jù)不需要來回復(fù)制,所以是最快的一種進(jìn)程間通信機(jī)制。共享內(nèi)存可以通過mmap()映射普通文件

(特殊情況下還可以采用匿名映射)機(jī)制實(shí)現(xiàn),也可以通過系統(tǒng)V共享內(nèi)存機(jī)制實(shí)現(xiàn)。應(yīng)用接口和原理很簡單,內(nèi)部機(jī)制復(fù)雜。為了實(shí)現(xiàn)更安全通信,往往還與信號燈等同步機(jī)制共同使用。

mmap的機(jī)制如:就是在磁盤上建立一個文件,每個進(jìn)程存儲器里面,單獨(dú)開辟一個空間來進(jìn)純團(tuán)行映射。如果多進(jìn)程的話拍戚,那么不會對實(shí)際的物理存儲器(主存)消耗太大。

shm的機(jī)制:每個進(jìn)程的共享內(nèi)存都直接映射到實(shí)際物理存儲器里面。

1、mmap保存到實(shí)際硬盤,實(shí)際存儲并沒有反映到主存上。優(yōu)點(diǎn):儲存量可以很大(多于主存);缺點(diǎn):進(jìn)程間讀取和寫入速度要比主存的要慢。

2、shm保存到物理存儲器(主存),實(shí)際的儲存量直接反映到主存上。優(yōu)點(diǎn),進(jìn)程間訪問速度(讀寫)比襲褲陵磁盤要快;缺點(diǎn),儲存量不能非常大(多于主存)

Linux的IPC機(jī)制(三):Binder

正如上一章所說, 跨進(jìn)程通信是需要內(nèi)核空間做支持的. 傳統(tǒng)的 IPC 機(jī)制如 管道, Socket, 都是內(nèi)核的一部分, 因此通過內(nèi)核支持來實(shí)現(xiàn)進(jìn)程間通信自然是沒問題的.

但是 Binder 并不是 Linux 系統(tǒng)內(nèi)核的一部分, 那怎么辦呢, 這得益于 Linux 的動態(tài)內(nèi)核可加載模塊 (Loadable Kernel Module, LKM)的鉛廳機(jī)制

這樣 Android 系統(tǒng)就可以通過動態(tài)添加一個內(nèi)核模塊運(yùn)行在內(nèi)核空間, 用戶進(jìn)程進(jìn)程之間通過這個內(nèi)核模塊作為橋梁來實(shí)現(xiàn)通信.

那么在 Android 系統(tǒng)中用戶進(jìn)程之間是如何通過這個內(nèi)核模塊 (Binder Driver)來實(shí)現(xiàn)通信的呢? 顯然不是和上一章的傳統(tǒng) IPC 通信一樣,進(jìn)行兩次 copy 了, 不然Binder 也不有在性能方面的優(yōu)勢了.

Binder IPC 機(jī)制中設(shè)計(jì)到的內(nèi)存映射通過 mmap() 來實(shí)現(xiàn), mmap() 是操作系統(tǒng)中一種內(nèi)存映射的方法.

內(nèi)存映射能減少數(shù)據(jù) copy 的次數(shù), 實(shí)現(xiàn)用戶空間和內(nèi)核空間的高效互動. 兩個空間各自的修改也能直接反應(yīng)在映射的內(nèi)存區(qū)域, 從而被對方空間及時感知. 也正因?yàn)槿绱? 內(nèi)存映射能夠提供對進(jìn)程間通信的支持.

Binder IPC 正是基于內(nèi)存映射( mmap() ) 來實(shí)現(xiàn)的, 但是 mmap() 通常是用在有物理介質(zhì)的文件系統(tǒng)上的.

比如進(jìn)程中的用戶區(qū)域是不能直接和物理設(shè)備打交道的, 如果想要把磁盤上的數(shù)據(jù)讀取到進(jìn)程的用戶區(qū)域, 需要兩次 copy (磁盤 -> 內(nèi)核空間 -> 用戶空間). 通常在這種場景下 mmap() 就能發(fā)揮作用, 通過在物理介質(zhì)和用戶空間之間建立映射, 減少數(shù)據(jù)的 copy 次數(shù), 用內(nèi)存讀寫代替 I/O 讀寫, 提高文件讀取效率.

而 Binder 并不存在物理介質(zhì), 因此 Binder 驅(qū)動使用 mmap() 并不是為了在物理介質(zhì)和用戶空間之間映射, 而是用來在內(nèi)核空間創(chuàng)建數(shù)據(jù)接收的緩存空間.

一次完整的 Binder IPC 通信過程通常是這樣:

這樣就完成了一次進(jìn)程間通信

如下圖:

介紹完 Binder IPC 的底層通信原理, 接下來我們看看實(shí)現(xiàn)層面是如何設(shè)計(jì)的

一次完成的進(jìn)程間通信必然至少包含兩個進(jìn)程, 通常我們稱通信的雙方分別為客戶端進(jìn)程(Client) 和服務(wù)端進(jìn)程(Server), 由于進(jìn)程隔離機(jī)制的存在, 通信雙方必然需要借助 Binder 來實(shí)現(xiàn).

BInder 是基于 C/S 架構(gòu). 是由一些列組件組尺雹成. 包括 Client, Server, ServiceManager, Binder 驅(qū)動.

Binder 驅(qū)動就如如同路由器一樣, 是整個通信的核心. 驅(qū)動負(fù)責(zé)進(jìn)程之間 Binder 通信的建立 / 傳遞, Binder 引用計(jì)數(shù)管理, 數(shù)據(jù)包在進(jìn)程之間的傳遞和交互等一系列底層支持.

ServiceManager 作用是將字符形式的 Binder 名字轉(zhuǎn)化成 Client 中對該 Binder 的引用, 使得 Client 能夠通過 Binder 的名字獲得對 Binder 實(shí)體的引用陵激帆.

注冊了名字的 Binder 叫實(shí)名 Binder, 就像網(wǎng)站一樣除了 IP 地址以外還有自己的網(wǎng)址.

Server 創(chuàng)建了 Binder, 并為它起一個字符形式, 可讀易記的名字, 將這個 BInder 實(shí)體連同名字一起以數(shù)據(jù)包的形式通過 Binder 驅(qū)動 發(fā)送給 ServiceManager, 通知 ServiceManager 注冊一個名字為 “張三”的 Binder, 它位于某個 Server 中, 驅(qū)動為這個穿越進(jìn)程邊界的 BInder 創(chuàng)建位于內(nèi)核中的實(shí)體節(jié)點(diǎn)以及 ServiceManager 對實(shí)體的引用, 將名字以及新建的引用打包傳給 ServiceManager, ServiceManager 收到數(shù)據(jù)后從中取出名字和引用填入查找表.

ServiceManager 是一個進(jìn)程, Server 又是一個另外的進(jìn)程, Server 向 ServiceManager 中注冊 BInder 必然涉及到進(jìn)程間通信. 當(dāng)實(shí)現(xiàn)進(jìn)程間通信又要用到進(jìn)程間通信, 這就好像蛋可以孵出雞的前提確實(shí)要先找只雞下蛋! Binder 的實(shí)現(xiàn)比較巧妙, 就是預(yù)先創(chuàng)造一只雞來下蛋. ServiceManager 和其他進(jìn)程同樣采用 Binder 通信, ServiceManager 是 Server 端, 有自己的 Binder 實(shí)體, 其他進(jìn)程都是 Client, 需要通過這個 Binder 的引用來實(shí)現(xiàn) Binder 的注冊, 查詢和獲取. ServiceManager 提供的 Binder 比較特殊, 它沒有名字也不需要注冊. 當(dāng)一個進(jìn)程使用 BINDERSETCONTEXT_MGR 命令將自己注冊成 ServiceManager 時 Binder 驅(qū)動會自動為它創(chuàng)建 Binder 實(shí)體(這就是那只預(yù)先造好的那只雞). 其實(shí)這個 Binder 實(shí)體的引用在所有 Client 中都固定為 0 , 而無需通過其他手段獲得. 也就是說, 一個 Server 想要向 ServiceManager 注冊自己的 Binder 就必須通過這個 0 號引用和 ServiceManager 的 Binder 通信. 這里說的 Client 是相對于 ServiceManager 而言的, 一個進(jìn)程或者應(yīng)用程序可能是提供服務(wù)的 Server, 但是對于 ServiceManager 來說它仍然是個 Client.

Server 向 ServiceManager 中注冊了 Binder 以后, Client 就能通過名字獲得 Binder 的引用. Client 也利用保留的 0 號引用向 ServiceManager 請求訪問某個 Binder. 比如,Client 申請?jiān)L問名字叫”張三”的 Binder 引用. ServiceManager 收到這個請求后從請求數(shù)據(jù)包中取出 Binder 名稱, 在查找表里找到對應(yīng)的條目, 取出對應(yīng)的 Binder 引用, 作為回復(fù)發(fā)送給發(fā)起請求的 Client. 從面相對象的角度看, Server 中的 Binder 實(shí)體現(xiàn)在有兩個引用: 一個位于 ServiceManager 中, 一個位于發(fā)起請求的 Client 中. 如果后面會有更多的 Client 請求該 Binder, 系統(tǒng)中就會有更多的引用指向這個 Binder, 就像 Java 中一個對象有多個引用一樣.

我們已經(jīng)解釋清楚 Client, Server 借助 Binder 驅(qū)動完成跨進(jìn)程通信的實(shí)現(xiàn)機(jī)制了, 但是還有個問題需要弄清楚, 比如 A 進(jìn)程想要 B 進(jìn)程中的某個對象(object) 是如何實(shí)現(xiàn)的呢, 畢竟它們屬于不同的進(jìn)程, A 進(jìn)程沒辦法直接使用 B 進(jìn)程中的 object.

前面我們說過跨進(jìn)程通信的過程都有 Binder 驅(qū)動的參與, 因此在數(shù)據(jù)流經(jīng) Binder 驅(qū)動的時候 Binder 驅(qū)動會對數(shù)據(jù)做一層轉(zhuǎn)換.

我們在 Client端,向 ServiceManager 獲取具體的 Server 端的 Binder 引用的時候,會首先進(jìn)過 Binder 驅(qū)動,Binder 驅(qū)動它并不會把真正的 Server 的 Binder 引用返回給 Client 端,而是返回一個代理的 java 對象,該對象具有跟 Server 端的 Binder 引用相同的方法簽名,這個對象為 ProxyObject,他具有跟 Server 的 Binder 實(shí)例一樣的方法,只是這些方法并沒有 Server 端的能力,這些方法只需要把請求參數(shù)交給 Binder 驅(qū)動即可. 對于 Client 端來說和直接調(diào)用 Server 中的方法是一樣的.

了解了上面之后, 我們大致可以推算出 Binder 的通信過程

1. 注冊 ServiceManager

2. 注冊 Server

3. Client 獲取 Server 的 Binder 引用

4. Client 與 Server 通信

關(guān)于linux mmap 實(shí)現(xiàn)的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

創(chuàng)新互聯(lián)-老牌IDC、云計(jì)算及IT信息化服務(wù)領(lǐng)域的服務(wù)供應(yīng)商,業(yè)務(wù)涵蓋IDC(互聯(lián)網(wǎng)數(shù)據(jù)中心)服務(wù)、云計(jì)算服務(wù)、IT信息化、AI算力租賃平臺(智算云),軟件開發(fā),網(wǎng)站建設(shè),咨詢熱線:028-86922220


分享名稱:深入探究Linuxmmap的實(shí)現(xiàn)方式(linuxmmap實(shí)現(xiàn))
鏈接URL:http://www.dlmjj.cn/article/ccooecg.html