歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

epoll事件處理的技術內核分析

epoll高效機制其實就是內核回調,我們知道linux把socket也是當成file處理的,只是底層驅動不一樣。

先來看看內核文件結構:

struct file_operations {  
       struct module *owner;  
       loff_t (*llseek) (struct file *, loff_t, int);  
       ssize_t (*read) (struct file *, char *, size_t, loff_t *);  
       ssize_t (*write) (struct file *, const char *, size_t, loff_t *);  
       int (*readdir) (struct file *, void *, filldir_t);  
       unsigned int (*poll) (struct file *, struct poll_table_struct *);  
       int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);  
       ..

可以看到結構體中有一個 poll 函數,這部分由驅動實現,其核心函數是:

static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)  
{  
    if (p && wait_address)  
        p->qproc(filp, wait_address, p);  
}

polltable 其實不是表,是一個結構體:

typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);  
typedef struct poll_table_struct {  
    poll_queue_proc qproc;  
} poll_table;

包含一個回調函數,當驅動有事件的時候,會調用這個回調。由此可以將epoll 內核實現分成兩層:業務層和驅動層。業務層實現epoll的各個函數,並將新增文件加到驅動層中,驅動層實現有事件時通知業務層。業務層有兩個函數與驅動層交互:設置隊列函數A,異步回調函數B

poll_table pt;  
pt.qproc = A;

當新增一個文件 sockt1 時,會調用

tfile->f_op->poll(socket1, &pt );

A立即調用,A要負責創建一個隊列元素,該隊列元素包含異步回調函數B,並將該元素插入到驅動層隊列中。當驅動層有事件時,會回調B,B再將對應socket1 插入到通知列表中,由epoll_wait 取走。這樣,epoll 的內核實現就清晰了,希望對大家有所幫助。

Copyright © Linux教程網 All Rights Reserved