linux .poll?Linux6.7
大家好,今天小编来为大家解答linux .poll这个问题,Linux6.7很多人还不知道,现在让我们一起来看看吧!
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平台上基于响应式流规范构建非阻塞异步应用。它是一个完全非阻塞响应式编程的基石。
Linuxpoll机制详细讲解
所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数。比如系统调用open、read、write、poll,与之对应的内核函数为:sys_open、sys_read、sys_write、sys_poll。
一、内核框架:
对于系统调用poll或select,它们对应的内核函数都是sys_poll。分析sys_poll,即可理解poll机制。
1.
sys_poll函数位于fs/select.c文件中,代码如下:
asmlinkage long sys_poll(struct pollfd __user*ufds, unsigned int nfds,long timeout_msecs){s64 timeout_jiffies;if(timeout_msecs> 0){#if HZ> 1000/* We can only overflow if HZ> 1000*/if(timeout_msecs/ 1000>(s64)0x7fffffffffffffffULL/(s64)HZ)timeout_jiffies=-1;else#endiftimeout_jiffies= msecs_to_jiffies(timeout_msecs);} else{/* Infinite(< 0) or no(0) timeout*/timeout_jiffies= timeout_msecs;}return do_sys_poll(ufds, nfds,&timeout_jiffies);}它对超时参数稍作处理后,直接调用do_sys_poll。
2.
do_sys_poll函数也位于位于fs/select.c文件中,我们忽略其他代码:
int do_sys_poll(struct pollfd __user*ufds, unsigned int nfds, s64*timeout){……poll_initwait(&table);……fdcount= do_poll(nfds, head,&table, timeout);……}poll_initwait函数非常简单,它初始化一个poll_wqueues变量table:
poll_initwait> init_poll_funcptr(&pwq->pt, __pollwait);> pt->qproc= qproc;
即table->pt->qproc= __pollwait,__pollwait将在驱动的poll函数里用到。
3.
do_sys_poll函数位于fs/select.c文件中,代码如下:
static int do_poll(unsigned int nfds,struct poll_list*list,struct poll_wqueues*wait, s64*timeout){01……02for(;;){03……04if(do_pollfd(pfd, pt)){05count++;06pt= NULL;07}08……09if(count||!*timeout|| signal_pending(current))10break;11count= wait->error;12if(count)13break;1415if(*timeout 0){16/* Wait indefinitely*/17__timeout= MAX_SCHEDULE_TIMEOUT;18} else if(unlikely(*timeout>=(s64)MAX_SCHEDULE_TIMEOUT-1)){19/*20* Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in21* a loop22*/23__timeout= MAX_SCHEDULE_TIMEOUT- 1;24*timeout-= __timeout;25} else{26__timeout=*timeout;27*timeout= 0;28}2930__timeout= schedule_timeout(__timeout);31if(*timeout>= 0)32*timeout+= __timeout;33}34__set_current_state(TASK_RUNNING);35return count;36}分析其中的代码,可以发现,它的作用如下:
①从02行可以知道,这是个循环,它退出的条件为:
a. 09行的3个条件之一(count非0,超时、有信号等待处理)
count顺0表示04行的do_pollfd至少有一个成功。
b. 11、12行:发生错误
②重点在do_pollfd函数,后面再分析
③第30行,让本进程休眠一段时间,注意:应用程序执行poll调用后,如果①②的条件不满足,进程就会进入休眠。那么,谁唤醒呢?除了休眠到指定时间被系统唤醒外,还可以被驱动程序唤醒──记住这点,这就是为什么驱动的poll里要调用poll_wait的原因,后面分析。
4.
do_pollfd函数位于fs/select.c文件中,代码如下:
static inline unsigned int do_pollfd(struct pollfd*pollfd, poll_table*pwait){……if(file->f_op&& file->f_op->poll)mask= file->f_op->poll(file, pwait);……}可见,它就是调用我们的驱动程序里注册的poll函数。
二、驱动程序:
驱动程序里与poll相关的地方有两处:一是构造file_operation结构时,要定义自己的poll函数。二是通过poll_wait来调用上面说到的__pollwait函数,pollwait的代码如下:
static inline void poll_wait(struct file* filp, wait_queue_head_t* wait_address, poll_table*p){if(p&& wait_address)p->qproc(filp, wait_address, p);}p->qproc就是__pollwait函数,从它的代码可知,它只是把当前进程挂入我们驱动程序里定义的一个队列里而已。它的代码如下:
static void __pollwait(struct file*filp, wait_queue_head_t*wait_address,poll_table*p){struct poll_table_entry*entry= poll_get_entry(p);if(!entry)return;get_file(filp);entry->filp= filp;entry->wait_address= wait_address;init_waitqueue_entry(&entry->wait, current);add_wait_queue(wait_address,&entry->wait);}执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout= schedule_timeout(__timeout)”。
poll_wait只是把本进程挂入某个队列,应用程序调用poll> sys_poll> do_sys_poll> poll_initwait,do_poll> do_pollfd>我们自己写的poll函数后,再调用schedule_timeout进入休眠。如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:chedule_timeout(__timeout),只是休眠__time_out这段时间。
现在来总结一下poll机制:
1. poll> sys_poll> do_sys_poll> poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。
2.接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数
它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;
它还判断一下设备是否就绪。
3.如果设备未就绪,do_sys_poll里会让进程休眠一定时间
4.进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。
5.如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作,直到应用程序的poll调用传入的时间到达。
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.