linux C epoll 水平触发与边缘触发详解

poll有两种触发方式

水平触发(level trigger,LT)与 边沿触发(edge trigger,ET)

水平触发与边缘触发的区别:

水平触发:只要缓冲区有数据就会一直触发

边沿触发:只有在缓冲区增加数据的那一刻才会触发

/* 使用边沿触发 */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
 
int main(int argc, char *argv[])
{
    int epfd, nfds;
    struct epoll_event event, events[10];
    int i;
		
    epfd = epoll_create(10);
    event.data.fd = 0; /* 监听标准输入 */
    event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
    //event.events = EPOLLIN; /* 读监听、水平触发 */
    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
	
    while (1) 
    {
 
        
        nfds = epoll_wait(epfd, events, 10, -1); /* 放回就绪的描述符数量 */
		
        for (i = 0; i < nfds; i++) 
        {
            if (events[i].data.fd == 0) 
            {
                printf("hello world\n");
            }
        }
    }
	
	return 0;
}

以上程序对于水平触发的情况下,只要终端输入数据,就会一直打印hello world

对于边缘触发,当终端输入一行, 只会打印一次hello world

下面解释为什么使用边缘触发必须使用非阻塞

在设置边缘触发时,因为每次发消息只会触发一次(不管缓存区是否还留有数据),所以必须把数据一次性读取出来,否则会影响下一次消息

下面的代码实现的是监听文件描述符,每次固定读取5个字节

先看下面这段代码

int main(int argc, char *argv[])
{
    int epfd, nfds;
    int i;
    struct epoll_event event, events[10];
    char buf[5];
    int flag;
	
    epfd = epoll_create(10);
    event.data.fd = 0; /* 监听标准输入 */
    event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
    //event.events = EPOLLIN; /* 读监听、水平触发 */
    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
 
#if 0           // 设置为非阻塞的读写
	flag = fcntl(0, F_GETFL);
	fcntl(0, F_SETFL, flag | O_NONBLOCK);
#endif	
 
    while (1)
    {
        int i;
        int num = 0;
        char c;
		
        nfds = epoll_wait(epfd, events, 5, -1); /* 返回就绪的文件描述符 */
		
        for (i = 0; i < nfds; ++i) 
        {
            if (events[i].data.fd == STDIN_FILENO) 
            {
                for(i = 0; i < 5; i++)
                {
                    buf[i] = getc(stdin);
                    if(buf[i] == -1)
                        break;
                }
 
                printf("hello world\n");
            }
            
        }
    }
	
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wwxy1995/article/details/94410678