How to replace select () with kevent () for better performance?

From the Kqueue Wikipedia Page :

Kqueue provides efficient event input and output pipelines between the kernel and the user environment. Thus, it is possible to change event filters, as well as receive pending events when using only one system call (2) for each iteration of the main event cycle. This contrasts with the older traditional polling system calls, such as polling (2) and select (2), which are less efficient, especially when polling events on a large number of file descriptors

Sounds great. I am targeting FreeBSD for my server and I am handling a significant portion of the fd network socket - using select () for everyone and figuring out who to read the data from. I would prefer to use kevent () calls to get better performance, as it is needed for this!

I read the man page for kevent on FreeBSD here , but it is cryptic for me and I do not find any good resources that explain it. An example of using kevent to replace select will solve my problem and also help me better understand how kevent () is used.

+6
source share
2 answers

First create a new kqueue:

int kq=kqueue(); 

Now register your fd in kq:

 struct kevent kev; kev.ident=your_fd; kev.flags=EV_ADD | EV_CLEAR; kev.filter=EVFILT_READ; kev.fflags=0; kev.data=0; kev.udata=&your_data; int res=kevent(kq,&kev,1,0,0,0); 

Finally, wait for the data to arrive on your socket:

 struct kevent res_kevs[5]; int res=kevent(kq,0,0,res_kevs,5,0); 

After returning res_kevs[i].ident will contain a handle to your socket, res_kevs[i].data - the number of bytes ready to be read.

See man kevent for more information and features.

+11
source

What you usually do is use libevent, which takes care of all the details for you, and also means that you can move your program to another OS that has a different circuit (like Linux and epoll) to do something similar.

-1
source

Source: https://habr.com/ru/post/886479/


All Articles