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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Android應(yīng)用程序消息處理機(jī)制(Looper、Handler)分析(4)

管道是Linux系統(tǒng)中的一種進(jìn)程間通信機(jī)制,具體可以參考前面一篇文章Android學(xué)習(xí)啟動(dòng)篇推薦的一本書《Linux內(nèi)核源代碼情景分析》中的第6 章--傳統(tǒng)的Uinx進(jìn)程間通信。

創(chuàng)新互聯(lián)建站10多年成都定制網(wǎng)頁設(shè)計(jì)服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計(jì)及高端網(wǎng)站定制服務(wù),成都定制網(wǎng)頁設(shè)計(jì)及推廣,對(duì)水泥攪拌車等多個(gè)方面擁有多年設(shè)計(jì)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。

簡單來說,管道就是一個(gè)文件,在管道的兩端,分別是兩個(gè)打開文件文件描述符,這兩個(gè)打開文件描述符都是對(duì)應(yīng)同一個(gè)文件, 其中一個(gè)是用來讀的,別一個(gè)是用來寫的,一般的使用方式就是,一個(gè)線程通過讀文件描述符中來讀管道的內(nèi)容,當(dāng)管道沒有內(nèi)容時(shí),這個(gè)線程就會(huì)進(jìn)入等待狀態(tài), 而另外一個(gè)線程通過寫文件描述符來向管道中寫入內(nèi)容,寫入內(nèi)容的時(shí)候,如果另一端正有線程正在等待管道中的內(nèi)容,那么這個(gè)線程就會(huì)被喚醒。

這個(gè)等待和喚醒 的操作是如何進(jìn)行的呢,這就要借助Linux系統(tǒng)中的epoll機(jī)制了。

Linux系統(tǒng)中的epoll機(jī)制為處理大批量句柄而作了改進(jìn)的poll,是Linux下多路復(fù)用IO接口select/poll的增強(qiáng)版本,它能顯著減 少程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率。

但是這里我們其實(shí)只需要監(jiān)控的IO接口只有mWakeReadPipeFd一個(gè),即前面我們所創(chuàng)建的管道的讀端,為什么還需要用到epoll呢?有點(diǎn)用牛刀來殺雞的味道。

其實(shí)不然,這個(gè)looper類是非常強(qiáng)大的,它除了監(jiān)控內(nèi)部所創(chuàng)建的管 道接口之外,還提供了addFd接口供外界面調(diào)用,外界可以通過這個(gè)接口把自己想要監(jiān)控的IO事件一并加入到這個(gè)Looper對(duì)象中去,當(dāng)所有這些被監(jiān)控 的IO接口上面有事件發(fā)生時(shí),就會(huì)喚醒相應(yīng)的線程來處理,不過這里我們只關(guān)心剛才所創(chuàng)建的管道的IO事件的發(fā)生。

我們?cè)倩氐絅ativeMessageQueue的構(gòu)造函數(shù)中,看看JNI層的Looper對(duì)象的創(chuàng)建過程,即看看它的構(gòu)造函數(shù)是如何實(shí)現(xiàn)的,這個(gè)Looper類實(shí)現(xiàn)在frameworks/base/libs/utils/Looper.cpp文件中:

 
 
  1. [cpp] view plaincopyLooper::Looper(bool allowNonCallbacks) : 
  2. mAllowNonCallbacks(allowNonCallbacks), 
  3. mResponseIndex(0) { 
  4. int wakeFds[2]; 
  5. int result = pipe(wakeFds); 
  6. ...... 
  7. mWakeReadPipeFd = wakeFds[0]; 
  8. mWakeWritePipeFd = wakeFds[1]; 
  9. ...... 
  10. #ifdef LOOPER_USES_EPOLL 
  11. // Allocate the epoll instance and register the wake pipe. 
  12. mEpollFd = epoll_create(EPOLL_SIZE_HINT); 
  13. ...... 
  14. struct epoll_event eventItem; 
  15. memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members 
  16.  data field union 
  17. eventItem.events = EPOLLIN; 
  18. eventItem.data.fd = mWakeReadPipeFd; 
  19. result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & 
  20. entItem); 
  21. ...... 
  22. #else 
  23. ...... 
  24. #endif 
  25. ...... 

這個(gè)構(gòu)造函數(shù)做的事情非常重要,它跟我們后面要介紹的應(yīng)用程序主線程在消息隊(duì)列中沒有消息時(shí)要進(jìn)入等待狀態(tài)以及當(dāng)消息隊(duì)列有消息時(shí)要把應(yīng)用程序主線程喚醒的這兩個(gè)知識(shí)點(diǎn)息息相關(guān)。它主要就是通過pipe系統(tǒng)調(diào)用來創(chuàng)建了一個(gè)管道了:

 
 
  1. [cpp] view plaincopyint wakeFds[2]; 
  2.  int result = pipe(wakeFds); 
  3.  ...... 
  4.  mWakeReadPipeFd = wakeFds[0]; 
  5.  mWakeWritePipeFd = wakeFds[1];

要使用Linux系統(tǒng)的epoll機(jī)制,首先要通過epoll_create來創(chuàng)建一個(gè)epoll專用的文件描述符:

 
 
  1. [cpp] view plaincopymEpollFd = epoll_create(EPOLL_SIZE_HINT); 

傳入的參數(shù)EPOLL_SIZE_HINT是在這個(gè)mEpollFd上能監(jiān)控的***文件描述符數(shù)。


網(wǎng)頁標(biāo)題:Android應(yīng)用程序消息處理機(jī)制(Looper、Handler)分析(4)
當(dāng)前網(wǎng)址:http://www.dlmjj.cn/article/ccsgsij.html