我是靠谱客的博主 瘦瘦爆米花,最近开发中收集的这篇文章主要介绍浅谈epoll的水平触发与边沿触发,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

概念

若监听的套接字描述符上有数据可读或可写,LT模式(水平触发)和ET模式(边沿触发)两种模式对应不同的通知模式。
        LT模式会不断的通知监听的套接字有数据可读或可写(对应套接字的读缓冲区不为空或写缓冲区不为满)
        ET模式只仅仅通知一次监听的套接字有数据可读或可写,除非缓冲区状态变化(读缓冲区由空变为非空,写缓冲区由满变为非满)才去通知相应事件。

几种IO复用模型对应的监听套接字的触发模型如下:

I/O模式水平触发边沿触发
select(), poll()支持不支持
信号驱动I/O不支持支持
epoll()支持(默认)支持

案例

学习了概念知识,接下来用一个案例进一步理解跟巩固所学概念,案例代码如下:

/**************************************
作   者 : lijd
生成日期 : 2021年02月04日
功能描述 : 测试epoll的水平触发和边沿触发
**************************************/ 
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/epoll.h>

int main(int argc, char *argv[])
{
    int iEpollType = 0;
    if(argc != 2)
    {
        perror("arg error! please cheak.");
        return -1;
    }
	
    0 == strcmp("LT", argv[1]) ? iEpollType = 1 : 0;
    0 == strcmp("ET", argv[1]) ? iEpollType = 2 : 0;
	
    if(iEpollType == 0)
    {
        perror("arg[1] error! is LT or ET.");
        return -1;
    }
    
    printf("iEpollType : %dn", iEpollType);
		
    int fd[2];
    int ret = pipe(fd);
    if(ret == -1)
    {
        perror("pipe error");
        return 1;
    }
	
    pid_t id = fork();
    if(id == 0)	//child
    {
        close(fd[0]); // 关闭输出
        while(1)
        {
            char test[] = "aaaaaabbbbbb";		// 一次写入12个字符
            write(fd[1], test, strlen(test));
	    printf("child send:%sn", test);
	    sleep(5);
	}
    }
    else if(id > 0)	//father
    {
	close(fd[1]);	 // 关闭输出
		
	struct epoll_event ev;
	struct epoll_event recvev[5];
	int i, res, len, efd;
	char buff[12] = {0};
		
	efd = epoll_create(5);
		
	iEpollType == 1 ? (ev.events = EPOLLIN) : (ev.events = EPOLLIN|EPOLLET);
	ev.data.fd = fd[0];
		
	epoll_ctl(efd, EPOLL_CTL_ADD, fd[0], &ev);
		
	while(1)
	{
	    res = epoll_wait(efd, recvev, 5, -1);
			
	    for(i = 0; i < res; i++)
	    {
		if(recvev[i].data.fd == fd[0])
		{
		    len = read(fd[0], buff, 6);	// 一次读6个字符
		    printf("father recv:%sn", buff);
		}
	    }
	}
    }
    else
    {
	perror("fork error");
	return 2;
    }
    
    return 0;
}

程序执行结果如下:

由上图程序执行结果让我们更进一步加强了对这两种触发模式的理解。根据上述的例子分析,LT模式:父进程每次收到子进程的数据时,它的套接字缓冲区中的数据通过epoll_wait()函数的2次触发而被读空;ET模式:父进程每次收到子进程的数据时,它的套接字缓冲区中的数据通过epoll_wait()函数的1次触发后读取部分数据,每次缓冲区中都有数据剩余。

最后

以上就是瘦瘦爆米花为你收集整理的浅谈epoll的水平触发与边沿触发的全部内容,希望文章能够帮你解决浅谈epoll的水平触发与边沿触发所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部