poll:和select差不多
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
与select共同点:还是轮询(轮询结构体数组)
区别1:监视的不是描述符号集合,是结构体数组
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events 需要监视的事件 */
short revents; /* returned events 监视时产生的事件 */
};
区别2:没有最大描述符号限制
区别3:不阻塞
poll编程模型:
1.创建结构体数组
2.设置要监视的描述符号
3.监视
4.根据返回值响应
select和poll在fd数量300以下时性能非常好
epoll:非阻塞,中断机制
#include <sys/epoll.h>
epoll编程模型:
1.创建epoll epoll_create(man epoll_create)
int epoll_create(int size);
2.注册fd对应的事件 epoll_ctl(man epoll_ctl)
int epoll_ctl(
int epfd, //epoll_create返回值
int op, //操作
//EPOLL_CTL_ADD 增加
//EPOLL_CTL_MOD 修改
//EPOLL_CTL_DEL 删除
int fd, //文件描述符号
struct epoll_event *event //epoll事件
//EPOLLIN
//EPOLLOUT
//EPOLLERR
//epoll要给每个监视的描述符号都注册对应的事件(和信号处理类似)
//如果有事件发生,就中断
);
3.等待 epoll_wait(man epoll_wait)
int epoll_wait(int epfd,
struct epoll_event *events,
int maxevents,
int timeout
);
4.检查和事件响应 if(&)
// poll
void _poll()
{
// 1.创建结构体数组
struct pollfd fds[200] = {0};
// 2.设置要监视的描述符号
int num = 0; // 已有的需要监视的fd数量
fds[0].fd = 0;
fds[0].events = POLLIN;
num++; // 添加了一个就+1
// 3.监视
char buff[1024];
while (1)
{
int r = poll(fds, num, 0);
if (-1 == r)
{
printf("poll 异常:%m\n");
return -1;
}
else if (0 == r)
{
continue;
}
else
{
// 4.根据返回值响应
printf("poll 接收到了返回值\n");
if (fds[0].events & POLLIN)
{
memset(buff, 0, 1024);
scanf("%s", buff);
printf("接收到:%s\n", buff);
}
}
}
}
// epoll
void _epoll()
{
// 1.创建epoll
int epfd = epoll_create(100);
if (-1 == epfd)
{
printf("创建epfd失败:%m\n");
return;
}
printf("创建epfd成功\n");
// 2.注册fd对应的事件
struct epoll_event ev = {0};
ev.events = EPOLLIN;
ev.data.fd = 0;
int r = epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev);
if (-1 == r)
{
printf("注册事件失败:%m\n");
close(epfd);
return;
}
printf("注册事件成功\n");
// 3.等待
struct epoll_event evs[100] = {0};
while (1)
{
int ret = epoll_wait(epfd, evs, 100, 0);
if (-1 == ret)
{
printf("epoll_wait失败:%m\n");
close(epfd);
return;
}
else if (0 == ret)
{
// printf("没动静\n");
}
else
{
char buff[1024] = {0};
scanf("%s", buff);
printf("有动静%d,%s\n", ret, buff);
}
}
// 4.检查和事件响应
}