<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                原文出處——>[Android系統匿名共享內存Ashmem(Anonymous Shared Memory)在進程間共享的原理分析](http://blog.csdn.net/luoshengyang/article/details/6666491) 在前面一篇文章Android系統匿名共享內存Ashmem(Anonymous Shared Memory)驅動程序源代碼分析中,我們系統地介紹了Android系統匿名共享內存的實現原理,其中著重介紹了它是如何輔助內存管理系統來有效地管理內存的,在再前面一篇文章Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃中,我們還提到,Android系統匿名共享內存的另外一特點是通過Binder進程間通信機制來實現進程間共享的,本文中,將詳細介紹Android系統匿名共享內存是如何使用Binder進程間通信機制來實現進程間共享的。 由于Android系統匿名共享內存在進程間共享的原理涉及到Binder進程間通信機制的相關知識,所以希望讀者在繼續閱讀本文之前,最好對Android系統的Binder進程間通信機制有一定的了解,具體可以參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃這篇文章。 在Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃這篇文章中,我們舉了一個例子來簡要地介紹了Android系統的匿名共享內存機制及其使用方法,在這篇文章中,我們繼續以這個實例來說明Android系統的匿名共享內存是如何使用Binder進程間通信機制來實現進程間共享的。為了方便描述,結合前面的Binder進程間通信機制知識,我們通過下面這個序列圖來總結這個實例中的匿名共享內存文件的文件描述符在進程間傳輸的過程: ![](http://hi.csdn.net/attachment/201108/7/0_1312688202Zh8N.gif) 這里, 我們需要關注的便是虛線框部分了,它在Binder驅動程序中實現了在兩個進程中共享同一個打開文件的方法。我們知道,在Linux系統中,文件描述符其實就是一個整數。每一個進程在內核空間都有一個打開文件的數組,這個文件描述符的整數值就是用來索引這個數組的,而且,這個文件描述符只是在本進程內有效,也就是說,在不同的進程中,相同的文件描述符的值,代表的可能是不同的打開文件。因此,在進程間傳輸文件描述符時,不能簡要地把一個文件描述符從一個進程傳給另外一個進程,中間必須做一過轉換,使得這個文件描述在目標進程中是有效的,并且它和源進程的文件描述符所對應的打開文件是一致的,這樣才能保證共享。 在淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路一文中,我們介紹了用來傳輸的Binder對象的數據結構struct flat_binder_object,它定義在**kernel/common/drivers/staging/android/binder.h** 文件中: ~~~ /* * This is the flattened representation of a Binder object for transfer * between processes. The 'offsets' supplied as part of a binder transaction * contains offsets into the data where these structures occur. The Binder * driver takes care of re-writing the structure type and data as it moves * between processes. */ struct flat_binder_object { /* 8 bytes for large_flat_header. */ unsigned long type; unsigned long flags; /* 8 bytes of data. */ union { void *binder; /* local object */ signed long handle; /* remote object */ }; /* extra data associated with local object */ void *cookie; }; ~~~ 域type是一個枚舉類型,它的取值范圍是: ~~~ enum { BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), }; ~~~ 這里我們要介紹的Binder對象的type便是BINDER_TYPE_FD了,要傳輸的文件描述符的值保存在handle域中。 在Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析一文中,我們詳細介紹了Binder對象在進程間通信傳輸的完整過程,這里就不再詳述了,有興趣的讀都可以回過頭去參考一下。這里,我們只關注文件描述符類型的Binder對象在Binder驅動程序中的相關處理邏輯。 文件描述符類型的Binder對象在Binder驅動程序中的相關處理邏輯實現在binder_transact函數,這個函數定義在**kernel/common/drivers/staging/android/binder.c**文件中: ~~~ static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply) { struct binder_transaction *t; struct binder_work *tcomplete; size_t *offp, *off_end; struct binder_proc *target_proc; struct binder_thread *target_thread = NULL; struct binder_node *target_node = NULL; struct list_head *target_list; wait_queue_head_t *target_wait; struct binder_transaction *in_reply_to = NULL; struct binder_transaction_log_entry *e; uint32_t return_error; ...... offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); ...... off_end = (void *)offp + tr->offsets_size; for (; offp < off_end; offp++) { struct flat_binder_object *fp; ...... fp = (struct flat_binder_object *)(t->buffer->data + *offp); switch (fp->type) { ...... case BINDER_TYPE_FD: { int target_fd; struct file *file; if (reply) { if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; } } else if (!target_node->accept_fds) { binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; } file = fget(fp->handle); if (file == NULL) { binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fget_failed; } target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); if (target_fd < 0) { fput(file); return_error = BR_FAILED_REPLY; goto err_get_unused_fd_failed; } task_fd_install(target_proc, target_fd, file); if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); /* TODO: fput? */ fp->handle = target_fd; } break; ...... } } ...... } ~~~ 這里,我們先明確一下在Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃這篇文章中所舉的例子獲取匿名共享內存文件的文件描述符的場景。匿名共享內存文件是在Server進程創建的,Client通過IMemoryService.getFileDescriptor去獲取Server進程所創建的匿名共享內存文件的文件描述符,Server進程在返回這個文件描述符的過程中進入到Binder驅動程序,即這里的binder_transact函數。因此,這里的當前執行binder_transact函數的進程是Server進程,即源進程是Server進程,而目標進程是Client進程,就是這里的target_proc所表示的進程了。 函數binder_transaction處理文件描述符類型的Binder對象就在中間的for循環里面。 首先是獲得Binder對象,并保存在本地變量fp中: ~~~ fp = (struct flat_binder_object *)(t->buffer->data + *offp); ~~~ 文件描述符的值就保存在fp->handle中,通過fget函數取回這個文件描述符所對應的打開文件結構: ~~~ file = fget(fp->handle); ~~~ 這里的file是一個struct file指針,它表示一個打開文件結構。注間,在Linux系統中,打開文件結構struct file是可以在進程間共享的,它與文件描述符不一樣。 接著在目標進程中獲得一個空閑的文件描述符: ~~~ target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); ~~~ 現在,在目標進程中,打開文件結構有了,文件描述符也有了,接下來就可以把這個文件描述符和這個打開文件結構關聯起來就可以了: ~~~ task_fd_install(target_proc, target_fd, file); ~~~ 由于這個Binder對象最終是要返回給目標進程的,所以還要修改fp->handle的值,它原來表示的是在源進程中的文件描述符,現在要改成目標進程的文件描述符: ~~~ fp->handle = target_fd; ~~~ 這樣,對文件描述符類型的Binder對象的處理就完成了。目標進程拿到這個文件描述符后,就可以和源進程一起共享打開文件了。 至此,Android系統匿名共享內存利用Binder進程間通信機制來實現進程間共享的學習就結束了,整個Android系統匿名共享內存機制的學習也完成了,希望對讀者有所幫助,重新學習Android系統匿名共享內存機制請回到Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃一文。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看