select,poll和epoll的区别

Select就是通过监听事件写入到一个32个元素 累计1024位的long数组中(就是fed_sets结构体的内容),用户加入监听位,如果有监听事件发生就会改变位的标志。但这样会有两个缺点,一是监听的数量被限制在了1024(三种事件:可读,可写,异常),而且复杂的位操作,即使提供了多个操作宏,仍会感到编程的繁琐,还有每次调用select(是每次,进入循环后每次使用select前都要做得事)要重新把监听的描述符重新加入到相应的监听方式结构体fed_sets,最多要传入三种监听方式的fed_sets。而且如果要加入新的描述符后监听还要判断加入的新描述符是否大于nfds,更新nfds。因此是非常复杂的。

poll就是为了解决select这种不人性化的使用过程。

Poll则是使用了pollfd的结构体,里面设置为关注的描述符fd,事件类型events,和关注描述符的事件反馈revents

Event也用按位的标志来表示事件类型。初始设置好pollfd后,每次调用poll前也不用重新设置监听的描述符。可以是升级版的poll了。

但是pollselect总体来说都是轮询式的,也就是说每次调用完pollselect函数后我都要遍历整个监听队列,去寻找监听事件发生的描述符,这种复杂度是较高的。相当于0(n)

epoll则是回调试的,epoll_event 结构体里的events成员是事件,data成员下的fd成员为关注的描述符,一开始先设置一个epoll_event revent[N]的数组,这个数组将来会作为epoll_wait的参数,接受发生的事件。

epoll的使用,一开始创建一个监听队列,epoll_create();

然后将感兴趣的事件通过epoll_ctl()加入到监听队列。最后通过epoll_wait,得到发生的事件的更新过后的revent,并且epoll_wait返回的值是事件发生的数量,而全部发生的事件又保存在revents中,可以说是epoll的使用复杂度就是0(1),即只处理感兴趣的事件,其他的事件直接忽略。

你可能感兴趣的:(操作系统,linux,C语言)