Linux event poll

Linux event poll

首先使用一个东西之前至少要了解为什么要使用它,为什么需要poll这个操作,通常网络部分需要监听多个套接字,又要处理套接字,而在监听的过程中程序已经阻塞就不能去执行其他程序,所以需要引入IO复用

struct epoll_event数据结构

The struct epoll_event is defined as:

typedef union epoll_data {
    void    *ptr;
    int      fd;
    uint32_t u32;
    uint64_t u64;
} epoll_data_t;	//保存某个触发事件相关的数据

struct epoll_event {
    uint32_t     events;    /* Epoll events */
    epoll_data_t data;      /* User data variable */
};
/*
其中events表示感兴趣的事件和被触发的事件,可能的取值为:
EPOLLIN:表示对应的文件描述符可以读;
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数可读;
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET:    ET的epoll工作模式;
*/

epoll_create函数

创建epoll文件描述符,成功返回文件句柄,否返回-1 设置errno

#include <sys/epoll.h>

int epoll_create(int size);
int epoll_create1(int flags);

epoll_wait函数

轮询IO事件的产生

@epfd:由epoll_create生成的epoll专用的文件描述符;

@epoll_event:用于回传代处理事件的数组;

@maxevents:每次能处理的事件数;

@timeout:等待I/O事件发生的超时值;

返回值:success:发生的事件数

​ fail: 0

#include <sys/epoll.h>

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

epoll_ctl函数

操作epoll文件描述符事件, 成功返回0 失败返回-1 设置errno
@epfd: epoll_create创建的文件句柄
@op:事件操作
@fd:需要监听的文件句柄
@event:指向epll event指针

操作事件:

EPOLL_CTL_ADD:在文件描述符epfd引用的epoll实例上注册目标文件描述符fd,并将事件事件与链接到fd的内部文件关联起来。

EPOLL_CTL_MOD:更改与目标文件描述符fd关联的事件事件。

EPOLL_CTL_DEL:从epfd引用的epoll实例中删除(取消注册)目标文件描述符fd。该事件将被忽略

#include <sys/epoll.h>

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

例子:

#define MAX_NUM		40
typedef struct Event_data {
    struct epoll_event event;
    char path[1024];
}Event_data_s; *Event_data_p;

static int event_fd = 0;
static int fd[MAX_NUM] = {0};
pthread_t event_pthread;
pthread_t data_pthread;
Event_data_s Event_group[MAX_NUM];

void *event_process(void *arg)
{
   	struct epoll_event epoll_data;
	char path_buf[1024] = {0};
	int ret;
    
	event_fd = epoll_create(MAX_NUMM);
	if(event_fd < 0)
	{
		printf("create epoll fd fail %d%s\n", errno, strerror(errno));
		return -1;
	}
while(1)
{
    sleep(1);
	for(i = 0; i < MAX_NUM; i++)
	{
		snprintf(path_buf, sizeof(path_buf), "/dev/input/event%d", i);
		fd[i] = open(path_buf, O_RDWR | O_NONBLOCK);
        if(fd[i] < 0)
        {
            printf("open fd fail %s\n", strerror(errno));
            continue;
        }
        ret = epoll_ctl(event_fd, EPOLL_CTL_ADD, fd[i], &epoll_data);
        if(ret != 0)
        {
            close(fd[i]);
            fd[i] = -1;
            continue;
        }
        memcpy( Event_group[i].path, path_buf, sizeof(path_buf));
	}
}
}
void *data_process(void *arg)
{
    int ret = 0;
    int i = 0;
    char buf[1024] = {0};
    
    struct epoll_event events[MAX_NUM];
    while(1)
    {
        sleep(1)
        
		ret = epoll_wait(event_fd, events, MAX_NUM, 100);
        if(ret <= 0)
        {
           for(i; i<= MAX_NUM; i++)
           {
               if(access(Event_group[i].path, F_OK) != 0)
               {
                   epoll_ctl(event_fd, EPOLL_CTL_DEL, event[i], NULL);
                   close(event[i]);
                   event[i] = -1;
                  
               }  
           }
           continue;
        }
       
    }
}
int Event_init()
{
	pthread_create(&event_pthread, NULL, event_process, NULL);
    pthread_create(&data_pthread, NULL, data_process, NULL);
    
	pthread_detach(event_pthread);
    pthread_detach(data_pthread);

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值