Android進(jìn)程間通信-eventfd

eventfd 是 Linux 2.6.22后才開(kāi)始支持的一種IPC通信方式,它的作用主要時(shí)用來(lái)做事件通知,并且完全可以替代pipe,對(duì)于內(nèi)核來(lái)說(shuō),eventfd的開(kāi)銷(xiāo)更低,eventfd只需要?jiǎng)?chuàng)建一個(gè)虛擬文件,而pipe需要?jiǎng)?chuàng)建兩個(gè),并且可用于select或epoll等多路復(fù)用模型中,來(lái)實(shí)現(xiàn)異步的信號(hào)通知功能。

所以eventfd 是很好用的一種IPC方式,而且它的使用也簡(jiǎn)單。

#include<sys/eventfd.h>  
#include <unistd.h>
int eventfd(unsigned int initval,int flags);//創(chuàng)建eventfd
ssize_t write(int fd, const void *buf, size_t count);   //寫(xiě)數(shù)據(jù)
ssize_t read(int fd, void *buf, size_t count);     //讀數(shù)據(jù)

eventfd在內(nèi)核里的核心是一個(gè)計(jì)數(shù)器counter,它是一個(gè)uint64_t的整形變量counter,初始值為initval。

當(dāng)調(diào)用read() 函數(shù)讀取eventfd時(shí),會(huì)根據(jù)counter值執(zhí)行下列操作:

  • 如果當(dāng)前counter > 0,那么read返回counter值,并重置counter為0;
  • 如果當(dāng)前counter等于0,那么read 函數(shù)阻塞直到counter大于0,如果設(shè)置了NONBLOCK,那么返回-1。

當(dāng)調(diào)用write() 往eventfd寫(xiě)數(shù)據(jù)時(shí),我們只能寫(xiě)入一個(gè)64bit的整數(shù)value

Eventfd在Android中的使用場(chǎng)景

正是因?yàn)閑ventfd比管道更簡(jiǎn)單高效,所以在Android6.0之后,Looper的喚醒就換成了eventfd。

Looper::Looper(bool allowNonCallbacks) :
        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
        mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
        mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
    mWakeEventFd = eventfd(0, EFD_NONBLOCK);
    LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd.  errno=%d", errno);
?
    AutoMutex _l(mLock);
    rebuildEpollLocked();
}
?
void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
    ALOGD("%p ~ wake", this);
#endif
    uint64_t inc = 1;
    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
    if (nWrite != sizeof(uint64_t)) {
        if (errno != EAGAIN) {
            ALOGW("Could not write wake signal, errno=%d", errno);
        }
    }
}

可以看到,Looper的構(gòu)造函數(shù)中mWakeEventFd已經(jīng)由之前提到的pipe換成了evnentfd,wake()函數(shù)也不是之前的寫(xiě)入一個(gè)“w”字符,而是寫(xiě)入了一個(gè)64位整數(shù)1。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容