poll linux?队列poll函数

大家好,关于poll linux很多朋友都还不太明白,今天小编就来为大家分享关于队列poll函数的知识,希望对各位有所帮助!

Linux内核中select,poll和epoll的区别

随着2.6内核对epoll的完全支持,网络上很多的文章和示例代码都提供了这样一个信息:使用epoll代替传统的poll能给网络服务应用带来性能上的提升。但大多文章里关于性能提升的原因解释的较少,这里我将试分析一下内核(2.6.21.1)代码中poll与epoll的工作原理,然后再通过一些测试数据来对比具体效果。

POLL:

先说poll,poll或select为大部分Unix/Linux程序员所熟悉,这俩个东西原理类似,性能上也不存在明显差异,但select对所监控的文件描述符数量有限制,所以这里选用poll做说明。

poll是一个系统调用,其内核入口函数为sys_poll,sys_poll几乎不做任何处理直接调用do_sys_poll,do_sys_poll的执行过程可以分为三个部分:

1,将用户传入的pollfd数组拷贝到内核空间,因为拷贝操作和数组长度相关,时间上这是一个O(n)操作,这一步的代码在do_sys_poll中包括从函数开始到调用do_poll前的部分。

2,查询每个文件描述符对应设备的状态,如果该设备尚未就绪,则在该设备的等待队列中加入一项并继续查询下一设备的状态。查询完所有设备后如果没有一个设备就绪,这时则需要挂起当前进程等待,直到设备就绪或者超时,挂起操作是通过调用schedule_timeout执行的。设备就绪后进程被通知继续运行,这时再次遍历所有设备,以查找就绪设备。这一步因为两次遍历所有设备,时间复杂度也是O(n),这里面不包括等待时间。相关代码在do_poll函数中。

3,将获得的数据传送到用户空间并执行释放内存和剥离等待队列等善后工作,向用户空间拷贝数据与剥离等待队列等操作的的时间复杂度同样是O(n),具体代码包括do_sys_poll函数中调用do_poll后到结束的部分。

EPOLL:

接下来分析epoll,与poll/select不同,epoll不再是一个单独的系统调用,而是由epoll_create/epoll_ctl/epoll_wait三个系统调用组成,后面将会看到这样做的好处。

先来看sys_epoll_create(epoll_create对应的内核函数),这个函数主要是做一些准备工作,比如创建数据结构,初始化数据并最终返回一个文件描述符(表示新创建的虚拟epoll文件),这个操作可以认为是一个固定时间的操作。

epoll是做为一个虚拟文件系统来实现的,这样做至少有以下两个好处:

1,可以在内核里维护一些信息,这些信息在多次epoll_wait间是保持的,比如所有受监控的文件描述符。

2, epoll本身也可以被poll/epoll;

具体epoll的虚拟文件系统的实现和性能分析无关,不再赘述。

在sys_epoll_create中还能看到一个细节,就是epoll_create的参数size在现阶段是没有意义的,只要大于零就行。

接着是sys_epoll_ctl(epoll_ctl对应的内核函数),需要明确的是每次调用sys_epoll_ctl只处理一个文件描述符,这里主要描述当op为EPOLL_CTL_ADD时的执行过程,sys_epoll_ctl做一些安全性检查后进入ep_insert,ep_insert里将 ep_poll_callback做为回掉函数加入设备的等待队列(假定这时设备尚未就绪),由于每次poll_ctl只操作一个文件描述符,因此也可以认为这是一个O(1)操作

ep_poll_callback函数很关键,它在所等待的设备就绪后被系统回掉,执行两个操作:

1,将就绪设备加入就绪队列,这一步避免了像poll那样在设备就绪后再次轮询所有设备找就绪者,降低了时间复杂度,由O(n)到O(1);

2,唤醒虚拟的epoll文件;

最后是sys_epoll_wait,这里实际执行操作的是ep_poll函数。该函数等待将进程自身插入虚拟epoll文件的等待队列,直到被唤醒(见上面ep_poll_callback函数描述),最后执行ep_events_transfer将结果拷贝到用户空间。由于只拷贝就绪设备信息,所以这里的拷贝是一个O(1)操作。

还有一个让人关心的问题就是epoll对EPOLLET的处理,即边沿触发的处理,粗略看代码就是把一部分水平触发模式下内核做的工作交给用户来处理,直觉上不会对性能有太大影响,感兴趣的朋友欢迎讨论。

POLL/EPOLL对比:

表面上poll的过程可以看作是由一次epoll_create/若干次epoll_ctl/一次epoll_wait/一次close等系统调用构成,实际上epoll将poll分成若干部分实现的原因正是因为服务器软件中使用poll的特点(比如Web服务器):

1,需要同时poll大量文件描述符;

2,每次poll完成后就绪的文件描述符只占所有被poll的描述符的很少一部分。

3,前后多次poll调用对文件描述符数组(ufds)的修改只是很小;

Linux的poll机制linux的poll

libevent详解?

libevent是一个轻量级的开源的高性能的事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。

libevent支持多种I/O多路复用技术(epoll、poll、dev/poll、select和kqueue等),在不同的操作系统下,做了多路复用模型的抽象,可以选择使用不同的模型,通过事件函数提供服务。

在非阻塞模式上怎么知道recv接收数据完成?

以linux下tcpsocket编程为例:阻塞就是recv/read的时候socket接收缓冲区要是有数据就读,没数据我就一直睡觉赖着不走,直到有数据来了读完我才走。

send/write的时候,要是发送缓冲区满了,没有空间继续发送了我也一直睡觉赖着不走,直到发送缓冲区腾出足够的空间让我把数据全部塞到发送缓冲区里我才走。

(当然如果你通过setsockopt设置了读写超时,超时时间到了还是会返回-1和EAGAIN,不再睡觉等待)

非阻塞就是recv/read的时候,要是接收缓冲区有数据我就读完,没有数据我直接带着返回的-1和EGAIN走人,绝不睡觉等待耽误时间。

write/send的时候,要是发送缓冲区有足够的空间,就立刻把数据塞到发送缓冲区去,然后走人,如果发送缓存区满了,空间不足,那直接带着返回的-1和EAGAIN走人。至于IO多路复用,首先要理解的是,操作系统为你提供了一个功能,当你的某个socket接收缓存区有数据可读,或者发送缓冲区有空间可写的时候,它可以给你一个通知。

这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不做纯返回-1和EAGAIN的无用功。

写操作类似。

操作系统的这个功能通过select/poll/epoll之类的系统调用函数来使用,这些函数都可以同时监视多个描述符的读写就绪状况,这样,多个描述符的I/O操作都能在一个线程内完成,这就叫I/O多路复用,这里的“复用”指的是复用同一个线程。至于事件驱动,其实是I/O多路复用的一个另外的称呼。至于异步同步,我们常见的linux下的网络编程模型大部分都是同步io,以读操作为例,本质上都是需要用户调用read/recv去从内核缓冲区把数据读完再处理业务逻辑。

异步io则是内核已经把数据读好了,用户直接处理逻辑。

异步IO在linux下一般是用aio库。

epoll和reactor区别?

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

而Reactor是第四代响应式库,是一个响应式编程范式的实现,用于在JVM平台上基于响应式流规范构建非阻塞异步应用。它是一个完全非阻塞响应式编程的基石。

linux.poll

epoll实现原理?

Epoll是LinuxIO的多路复用的机制,是select/poll的增强版本,在Linux内核fs/eventpoll.c中可以查看epoll的具体的实现。

学习任何组件,首先得知道它有什么数据结构或者数据类型,epoll主要有两个结构体:eventpoll和epitem。epitem是每一个IO对应的事件,比如EPOLL_CTL_ADD操作时,就需要创建一个epitem;eventpoll是每一个epoll所对应的,比如epoll_create就是创建一个eventpoll。

libevent详解?

libevent是一个轻量级的开源的高性能的事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。

libevent支持多种I/O多路复用技术(epoll、poll、dev/poll、select和kqueue等),在不同的操作系统下,做了多路复用模型的抽象,可以选择使用不同的模型,通过事件函数提供服务。

如何在linuxsuse中配置NTP服务器?

在suse上配置ntp

$vim/etc/ntp.conf

#增加时间源

server192.168.56.1

$chkconfigntpon#在系统重启时启动服务

$servicentpstart#启动ntp

$servicentpstatus#查看ntp状态

问题:

1)为什么在故意改了一个错误的时间,ntpd没有更新时间?

如果差异很大,需要重新doinganInitialSynchronization,IfthetimeonthelocalserverisverydifferentfromthatofitsprimarytimeserveryourNTPdaemonwilleventuallyterminateitselfleavinganerrormessageinthe/var/log/messagesfile.Youshouldrunthentpdate-ucommandtoforceyourservertobecomeinstantlysynchronizedwithitsNTPserversbeforestartingtheNTPdaemonforthefirsttime.Thentpdatecommanddoesn'truncontinuouslyinthebackground,youwillstillhavetorunthentpddaemontogetcontinuousNTPupdates.

2)/etc/ntp.conf中选择主NTPServer

选择了哪个server做为主server是按stratum的大小决定的?应该不是,由ntp的算法决定,如在virtualbox中的suse怎么样都无法选择外部时钟源,ntpd在几次polltime后算法就决定使用local源,郁闷啊。由于是虚拟机中运行,时钟和cpu的频率有关系,跳得比真实的硬件快,在virtaulbox中ntp的算法认为local源比外部源更准确就使用了local的,解决的方法可以去掉local源,只使用外部源或者在crontab中每分钟执行一次ntpdate了。

即使把本机的stratum设置为比外部源更高的,过了一段时间以后,virtualbox中的suse还是选择了local,郁闷again

fudge127.127.1.0stratum12#notdisciplined

remoterefidsttwhenpollreachdelayoffsetjitter

==============================================================================

LOCAL(0).LOCL.15l96410.0000.0000.002

192.168.56.1139.114.32.13414u86413.739-53.0450.002

注意最开始的时候,ip地址前面是没有符号的,poll几次以后ntp就会选择一个主时间源,前面带*号标识。

3)windows上的ntpserver配置

官方ntp.org推荐的win上的ntpserver,

3)如何知道ntp的运行状态

使用ntpq命令

$watchntpq-p#可以使用watch命令来查看一段时间内服务器各项数值的变化

使用ntpq命令查看与您同步的服务器.它提供你一份时间服务器配置清单,包括延误值(delay),偏差值(offset)和抖动值(jitter).为了能正确同步,延迟值和偏移值应该不为零,抖动值(jitter)应小于100.

$/usr/local/ntp/bin/ntpq-p

显示如下:

remoterefidsttwhenpollreachdelayoffsetjitter

========================================================

time.nist.gov.ACTS.1u1606102422357.845334.37571.122

*LOCAL(0).LOCL.10l11643770.0000.0000.001

ntpq-p可以列出目前我们的NTP与相关的上层NTP的状态,几个字段的意义为:

remote:亦即是NTP主机的IP或主机名称_~注意最左边的符号,

*

它告诉我们远端的服务器已经被确认为我们的主NTPServer,我们系统的时间将由这台机器所提供

+

它将作为辅助的NTPServer和带有*号的服务器一起为我们提供同步服务.当*号服务器不可用时它就可以接管

-

远程服务器被clusteringalgorithm认为是不合格的NTPServer

x

远程服务器不可用

refid:参考的上一层NTP主机的地址

st:stratum阶层

when:几秒钟前曾经做过时间同步化更新的动作;

poll:下一次更新在几秒钟之后;

reach:已经向上层NTP服务器要求更新的次数

delay:网络传输过程当中延迟的时间,单位为10^(-6)秒

offset:时间补偿的结果,单位与10^(-6)秒

jitter:Linux系统时间与BIOS硬件时间的差异时间,单位为10^(-6)秒。

也可以检查一下BIOS时间与Linux系统时间的差异,就是/var/lib/ntp/drift的内容,就能了解到Linux系统时间与BIOS硬件时钟到底差多久?单位为10^(-6)秒

下面的从上摘下来的,详细说明了ntpq-p输出的每个列的意思,reach列为377表示前8次同步都成功。

CheckingtheNTPStatus

ThecommandlineutilityntpqcanbeusedtocheckthestatusofaNTPdaemononeitherthelocalmachineoronaremotehost.

ntpqcanberuninaninteractivemodeorinbatchmode.Inbatchmode,ntpqexecutesacommandandreturnstothecommandprompt.Theparameter-p('peers')letsntpqprintthestatusofaNTPdaemon.Enter

ntpq-p

todisplaythestatusofthedaemononthelocalmachine,or

ntpq-pntp_server

todisplaythestatusofthedaemonontheremotehostntp_server.ThecommandshouldprintatablewithonestatuslineforeachreferencetimesourcewhichhasbeenconfiguredfortheNTPdaemononthespecifiedhost:

remoterefidsttwhenpollreachdelayoffsetjitter

=======================================================================

LOCAL(0)LOCAL(0)12l30643770.0000.0000.000

*GENERIC(0).DCFa.0-24643770.0000.0500.003

+172.16.3.103.PPS.1u36643771.306-0.0190.043

ThetableaboveshowstheoutputforaNTPdaemonwhichhas3referencetimesources:itsownlocalclock,aDCF77radioclockasrefclock-0,plusanNTPdaemononthenetwork,withIPaddress172.16.3.103.

Ifthefirstcharacterofalineisnotblankthenitcontainsaqualifierforthecorrespondingreferencetimesource.Immediatelyafterthedaemonhasbeenstartedallqualifiersareblank.TheNTPdaemonneedsseveralpollingcyclestochecktheavailabletimesourcesanddeclareoneofthemasthereferenceitsynchronizesto.

Anasterisk*inthefirstcolumnmarksthereferencetimesourcewhichiscurrentlypreferredbytheNTPdaemon,the+charactermarkshighqualitycandidatesforthereferencetimewhichcouldbeusedifthecurrentlyselectedreferencetimesourceshouldbecomeunavailable.

ThecolumnremotedisplaystheIPaddressorthehostnameofthereferencetimesource,whereLOCALreferstothelocalclock.Therefidshowsthetypeofthereferenceclock,wheree.g.LOCALorLCLreferstothelocalclockagain,.DCFa.referstoastandardDCF77timesource,and.PPS.indicatesthatthereferenceclockisdisciplinedbyahardwarepulse-per-secondsignal.Otheridentifiersarepossible,dependingonthetypeofthereferenceclock.

Thecolumnstreflectsthestratumnumberofthereferencetimesource.Intheexampleabove,thelocalclockhasstratum12,theremotetimeserverat172.16.3.103hasstratum1whichisthebestyoucanseeacrossthenetwork,andthelocalradioclockhasstratum0,sotheradioclockiscurrentlybeingpreferred.

Everytimeawhencountreachesthepollnumberinthesameline,theNTPdaemonqueriesthetimefromthecorrespondingtimesourceandresetsthewhencountto0.Thequeryresultsofeachpollingcyclearefilteredandusedasameasurefortheclock'squalityandreachability.

Thecolumnreachshowsifareferencetimesourcecouldbereachedatthelastpollingintervals,i.e.datacouldbereadfromthereferencetimesource,andthereferencetimesourcewassynchronized.Thevaluemustbeinterpretedasan8bitshiftregisterwhosecontentsisforhistoricalreasonsdisplayedasoctalvalues.IftheNTPdaemonhasjustbeenstarted,thevalueis0.Eachtimeaquerywassuccessfula'1'isshiftedinfromtheright,soafterthedaemonhasbeenstartedthesequenceofreachnumbersis0,1,3,7,17,37,77,177,377.Themaximumvalue377meansthattheeightlastquerieswerecompletedsuccessfully.

Queriesareconsideredsuccessfulifdatacanbereceivedfromthetimesource,andthetimesourceinturnclaimstobesynchronizedtosomeothertimesource.Incaseofahardwarereferenceclockthismeansthequeryconsideredunsuccessfulifthehardwarereferenceclockisnotsynchronizedtoitsincomingtimesignal,e.g.becausetheclock'santennahasbeendisconnected,orifnodatacanbereceivede.g.becausetheserialcabletoanexternaldevicehasbeendisconnected.

TheNTPdaemonmusthavereachedareferencetimesourceseveraltimes(reachnot0)beforeitselectsapreferredtimesourceandputsanasteriskinthefirstcolumn.

Thecolumnsdelay,offsetandjittershowsometimingvalueswhicharederivedfromthequeryresults.Insomeversionsofntpqthelastcolumnislabeleddisp(fordispersion)insteadofjitter.Allvaluesareininmilliseconds.Thedelayvalueisderivedfromtheroundtriptimeofthequeries.Theoffsetvalueshowsthedifferencebetweenthereferencetimeandthesystemclock.Thejittervalueindicatesthemagnitudeofjitterbetweenseveraltimequeries.

阅读剩余
THE END