epoll_create
SYNOPSIS
#include <sys/epoll.h>
int epoll_create(int size);
int epoll_create1(int flags);
DESCRIPTION
epoll_create() creates an epoll(7) instance.
epoll_ctl
SYNOPSIS
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll_wait
SYNOPSIS
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define EPOLL_SIZE 1024
int main(int argc, char **argv)
{
struct sockaddr_in addr, clientaddr;
int sfd;
int cfd;
socklen_t clilen;
int flags = 1;
int n,i;
int readn;
struct epoll_event ev,*events;
int efd;
char buf_in[256];
events = (struct epoll_event *)malloc(sizeof(*events) * EPOLL_SIZE);
if ( 0 > (efd = epoll_create(EPOLL_SIZE)) )
{
perror("epoll_create error");
return 1;
}
clilen = sizeof(clientaddr);
sfd = socket(AF_INET, SOCK_STREAM, 0);
if ( -1 == sfd )
{
perror("socket error");
close(sfd);
return 1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[1]));
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ( -1 == bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) )
{
close(sfd);
return 1;
}
listen(sfd, 512);
ev.events = EPOLLIN;
ev.data.fd = sfd;
epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &ev);
while(1)
{
n = epoll_wait(efd, events, EPOLL_SIZE, -1);
if ( n == -1 )
{
perror("epoll wait error");
}
for ( i = 0; i < n; ++i)
{
//acept
if (events[i].data.fd == sfd)
{
printf("Accept\n");
cfd = accept(sfd, (struct sockaddr *)&clientaddr, &clilen);
ev.events = EPOLLIN;
ev.data.fd = cfd;
epoll_ctl(efd, EPOLL_CTL_ADD, cfd, &ev);
}
// worker
else
{
memset(buf_in, 0, 256);
readn = read(events[i].data.fd, buf_in, 255);
if (readn <= 0)
{
epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd, events);
close(events[i].data.fd);
printf("Close fd\n");
}
else
{
printf("read data %s\n", buf_in);
}
}
}
}
}
level trigger vs. edge trigger
일반적으로 level trigger 보다 edge trigger 가 성능이 좋다고 한다. 하지만 edge triggerr 로 동작할 때는 fd를 non-blocking 으로 설정하여야 한다.
참조: http://goldenretriever.tistory.com/entry/linux-epoll%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-echo-server