名称
EV-perl与libev的接口,这是一个高性能的全功能事件循环
简介
使用电动汽车;#计时器my$w=EV::计时器2,0,sub{警告“2s后调用”;};my$w=EV::计时器2、2、sub{warn“大约每2秒调用一次(repeat=2)”;};undef$w;#未定义再次销毁事件监视程序my$w=EV::周期0,60,0,sub{警告“每分钟、每分钟、准确地调用”;};#IO(输入输出)my$w=EV::io*STDIN,EV::READ,sub{my($w,$revents)=@_;#所有回调都接收观察程序和事件掩码警告“stdin可读,您输入了:”,<stdin>;};#信号my$w=EV::信号“QUIT”,sub{警告“收到sigquit”;};#儿童/PID状态更改我的$w=EV::child 666,0,sub{my($w,$revents)=@_;我的$status=$w->rstatus;};#统计数据变化my$w=EV::stat“/etc/passwd”,10,sub{my($w,$revents)=@_;warn$w->path,“不知怎么改变了。\n”;};#主回路EV::运行;#循环,直到调用EV::break或所有观察者停止EV::运行EV::run_ONCE;#阻止,直到可以处理至少一个事件EV::运行EV::run_NOWAIT;#尝试处理相同的事件,但不要阻止
开始使用本模块之前
如果您只需要计时器、I/O、信号、子和空闲观察程序,而不需要此模块的高级功能,请考虑使用任何事件相反,特别是中描述的简化API不良事件.
当使用EV作为后端时不良事件API与本机一样快电动汽车API,但您的程序/模块仍将与许多其他事件循环一起运行。
描述
此模块为libev提供了一个接口(http://software.schmorp.de/pkg/libev.html)。虽然下面的文档很全面,但也可以参考libev本身的文档(http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod或perldoc EV::libev)有关watcher语义的更详细信息,或有关可用后端的一些讨论,或如何使用LIBEV_堵塞
或者只是因为它有更详细的信息。
此模块非常快速且可扩展。它实际上非常快,您可以通过任何事件模块,保持对其他事件循环的可移植性(如果您不依赖任何通过它不可用的观察程序类型),并且仍然比Perl当前支持的任何其他事件循环更快。
EV 3.X至4.X的端口
EV版本4引入了此处总结的一些不兼容更改。根据libev使用的折旧策略,存在一个兼容层,因此程序应继续保持不变(XS接口缺少该层,因此使用该层的程序需要更新)。
此兼容层将在未来的某个版本中关闭。
与Perl相关的所有更改都是符号、函数和方法的重命名:
EV::回路=>EV::运行EV::LOOP_NONBLOCK=>EV::RUN_NOWAITEV::LOOP_ONESHOT=>EV::RUN_ONCEEV::卸载=>EV::中断EV::UNLOOP_CANCEL=>EV::中断_取消EV::UNLOOP_ONE=>EV::BREAK_ONEEV::unlop_ALL=>EV::BREAK_ALLEV::超时=>EV::计时器EV::loop_count=>EV::iterationEV::loop_depth=>EV::depthEV::loop_verify=>EV::verify
与上述函数对应的循环对象方法也进行了类似的重命名。
模块出口
此模块不导出任何符号。
事件循环
EV支持多个事件循环:有一个“默认事件循环”可以处理所有事情,包括信号和子观察程序,还有任意数量的“动态事件循环”,可以使用不同的后端(具有各种限制),但没有子观察程序和信号观察程序。
您无需执行任何操作即可创建默认事件循环:当加载模块时,在选择工作后端的前提下选择合适的后端(例如,这将排除大多数BSD上的kqueue)。除非模块有“特殊需要”,否则应该始终使用默认循环,因为这是最快的(perl-wise),最好由其他模块(例如AnyEvent或Coro)和最可移植的事件循环支持。
对于特定程序,可以动态创建其他事件循环。
如果您想利用kqueue(通常只适用于套接字),即使默认循环没有启用它,您也可以嵌入将kqueue循环转换为默认循环:运行默认循环也会在一定程度上为kqueue环路提供服务。有关如何实现这一点的示例,请参阅关于嵌入观察者的部分中的示例。
- $loop=新EV::loop[$flags]
-
根据指定的标志创建一个新的事件循环。请参阅ev_loop_new()
libev文档中的函数描述(http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#GLOBAL_FUNCTIONS,或本地安装为企业价值::libevmanpage)了解更多信息。
当任何观察者不再引用循环并且循环对象超出范围时,循环将自动被销毁。
如果不嵌入循环,则使用EV::FLAG_FORKCHECK(警告检查)
建议使用,因为此模块仅保护默认事件循环。如果你是将此循环嵌入默认循环中,这是不必要的,因为EV::嵌入
自动在fork上执行正确的操作。
- $loop->loop_fork
-
在进入或继续事件循环之前,必须在子级中的fork之后调用。另一种方法是使用EV::FLAG_FORKCHECK(警告检查)
它会自动调用此函数,但性能会有所损失(请参阅libev文档)。
- $loop->验证
-
电话ev_verify(验证)
进行内部一致性检查(用于调试libev),并在发现任何数据结构损坏时中止程序。
- $loop=EV::default_loop[$flags]
-
返回默认循环(这是一个单一对象)。由于此模块已经使用默认标志创建了默认循环,因此在此处指定标志将不会产生任何效果,除非您首先销毁默认循环,这是不受支持的。所以简而言之:不要这样做,如果你打破了它,你就可以保留碎片。
基本接口
- $EV::死亡
-
必须包含对回调抛出异常时调用的函数的引用($@包含错误)。默认情况下打印信息消息并继续。
如果此回调抛出异常,它将被自动忽略。
- $flags=EV::supported_backends
-
- $flags=EV::recommended_backends
-
- $flags=EV::embeddable_backends
-
返回集合(请参见EV::后端_*
标志)、该平台的一组推荐后端(应该是好的)和一组可嵌入后端(参见嵌入式手表)。
- EV::休眠$秒
-
在给定的秒数(小数)内阻止进程。
- $时间=EV::时间
-
返回自epoch以来的当前时间(小数)秒。
- $time=EV::现在
-
- $time=$loop->现在
-
返回上次事件循环迭代开始的时间。这是(相对)计时器所基于的时间,引用它通常比调用EV::time更快。
- EV::now_update(当前更新)
-
- $loop->now_update
-
通过查询内核来建立当前时间,更新返回的时间EV::现在
正在进行中。这是一项成本高昂的操作,通常在EV::运行
.
这个函数很少有用,但当某些事件回调运行很长时间而没有进入事件循环时,更新libev对当前时间的想法是一个好主意。
- EV::暂停
-
- $loop->挂起
-
- EV::恢复
-
- $loop->恢复
-
这两个函数暂停并恢复一个循环,以便在一段时间内不使用循环且不应处理超时时使用。
典型的用例是交互式程序,如游戏:当用户按下^Z
要暂停游戏并在一个小时后恢复,最好将超时处理为程序暂停时没有实际时间。这可以通过调用暂停
在您的SIGTSTP公司
处理程序,向自己发送SIGSTOP公司
和呼叫简历
然后直接恢复计时器处理。
有效地,所有计时器
观察者将被两次之间的时间延迟暂停
和简历
,以及所有周期性的
观察者将被重新安排(也就是说,他们将丢失暂停时发生的任何事件)。
打电话后暂停
你不能呼叫任何给定循环上的函数,而不是简历
,还有你不能呼叫简历
之前没有呼叫暂停
.
打电话暂停
/简历
具有更新事件循环时间的副作用(请参见现在更新(_U)
).
- $backend=EV::backend
-
- $backend=$loop->后端
-
返回描述libev使用的后端的整数(EV::backend_SELECT或EV::backend_EPOLL)。
- $active=EV::运行[$flags]
-
- $active=$loop->运行([$flags])
-
开始检查事件并调用回调。当回调调用EV::break或标志为非零时(在这种情况下,返回值为true),或者当没有引用循环的活动观察程序时(keepalive为true时),返回值将为false。返回值通常可以解释为“如果为true,则还有更多工作要做”。
$flags参数可以是以下之一:
0同上EV::RUN_ONCE块最多一次(等待,但不要循环)EV::RUN_NOWAIT根本不阻塞(获取/处理事件,但不等待)
- EV::中断[$how]
-
- $loop->break([$how])
-
如果调用时没有参数或参数为EV::BREAK_ONE,则对EV::run return进行最内层的调用。
当使用EV::BREAK_ALL参数调用时,所有对EV::run的调用都将尽快返回。
当使用EV::BREAK_CANCEL参数调用时,任何挂起的中断都将被取消。
- $count=EV::迭代
-
- $count=$loop->迭代
-
返回事件循环轮询新事件的次数。有时用作生成计数器。
- EV::一次$fh_or_undef,$events,$timeout,$cb->($revents)
-
- $loop->一次($fh_or_undef、$events、$timeout、$cb->($revents))
-
此函数将单个单发事件的I/O和计时器观察程序滚动在一起,而无需管理观察程序对象。
如果$fh或_undef
是文件句柄或文件描述符,则$个事件
必须是包含以下内容之一的位集EV::读取
,EV::写入
或EV::读| EV::写
,指示要等待的I/O事件类型。如果不想等待某些I/O事件,请指定未定义
对于$fh或_undef
和0
对于$个事件
).
如果超时为未定义
或者为负数,则没有超时。否则EV::计时器
将使用此值启动。
当发生错误或触发超时或I/O观察程序时,将使用接收到的事件集调用回调(通常您可以期望它是以下内容的组合EV::错误
,EV::读取
,EV::写入
和EV::计时器
).
EV::once不返回任何内容:观察程序保持活动状态,直到其中任何一个触发,然后将停止并释放它们,并调用回调。
- EV::feed_fd_event$fd,$revents
-
- $loop->feed_event($fd,$revents)
-
将文件描述符上的事件馈送到EV。EV将对此调用作出响应,如同$复仇
(以下各项的组合EV::读取
和EV::写入
)发生在文件描述符上美元fd
.
- EV::feed_signal_event$信号
-
将信号事件馈送到默认循环中。EV将对此呼叫作出响应,如同$信号
发生了。
- EV::feed_signal$信号
-
将信号事件输入电动汽车-不同于电动车辆::feed_signal_event
,无论哪个循环注册了信号,这都是有效的,并且主要用于自定义信号实现。
- EV::set_io_collect_interval$time
-
- $loop->set_io_collect_interval($time)
-
- EV::set_timeout_collect_interval$时间
-
- $loop->set_timeout_collect_interval($time)
-
这些高级函数设置轮询I/O事件时的最小块间隔和计时器事件的最小等待间隔。请参阅libev文档,网址为http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#FUNCTIONS_CONTROLLING_THE_EVENT_LOOP(本地安装为企业价值::libev)以进行更详细的讨论。
- $count=EV::pending_count
-
- $count=$loop->pending_count
-
返回当前挂起的观察程序数。
- EV::调用挂起
-
- $loop->调用挂起
-
调用所有当前挂起的观察程序。
观察者对象
观察者是一个创建用于记录您对某些事件的兴趣的对象。例如,如果您希望等待STDIN变为可读,您可以创建一个EV::io观察程序:
my$watcher=EV::io*STDIN,EV::READ,sub{my($watcher,$revents)=@_;警告“是的,STDIN现在应该是可读的,没有阻塞!\n”};
所有观察者都可以处于活动状态(等待事件)或非活动状态(暂停)。只有活动的观察者才会调用其回调。所有回调都将使用至少两个参数进行调用:观察程序和接收事件的位掩码。
每种观察程序类型都在revents中有其关联的位,因此您可以对多个观察程序使用相同的回调。事件掩码以类型命名,即EV::child set EV::child,EV::prepare set EV::prepare,EV::periodic set EV:∶periodic等,但i/O事件除外(它可以设置EV::READ和EV::WRITE位)。
在极少数情况下,如果希望创建观察程序但不同时启动它,则每个构造函数都有一个带有尾随的变量_纳秒
在其名称中,例如EV::io有一个非启动变量EV::io_ns等。
请注意,当观察程序对象被销毁时,观察程序将自动停止,因此您需要保存构造函数返回的观察程序对象。
此外,如果观察程序处于活动状态,所有更改观察程序某些方面的方法(->设置、->优先级、->fh等)都会自动停止并再次启动它,这意味着挂起的事件会丢失。
常见的监视方法
本节列出了所有观察者通用的方法。
- $w->开始
-
如果观察程序尚未处于活动状态,则启动该观察程序。对已激活的观察程序不执行任何操作。默认情况下,所有观察程序都以活动状态启动(请参阅_纳秒
变量(如果需要停止观察程序)。
- $w->停止
-
如果监视程序处于活动状态,请将其停止。同时清除所有挂起的事件(已收到但尚未导致回调调用的事件),无论观察程序是否处于活动状态。
- $bool=$w->处于活动状态
-
如果观察程序处于活动状态,则返回true,否则返回false。
- $current_data=$w->数据
-
- $old_data=$w->数据($new_data)
-
查询观察程序上可自由使用的数据标量,并可选择更改它。这是将自定义数据与观察程序关联的一种方法:
my$w=EV::计时器60,0,sub{警告$_[0]->数据;};$w->数据(“打印我!”);
- $current_cb=$w->cb
-
- $old_cb=$w->cb($new_cb)
-
查询观察程序上的回调并有选择地更改它。您可以随时执行此操作,而无需重新启动观察程序。
- $current_priority=$w->优先级
-
- $old_priority=$w->优先级($new_prioriity)
-
查询观察程序的优先级并有选择地更改它。优先级较高的挂起观察程序将首先被调用。优先级的有效范围介于EV::MAXPRI(默认值2)和EV::MINPRI(默认值-2)之间。如果优先级在该范围之外,它将自动标准化为最接近的有效优先级。
任何新创建的观察程序的默认优先级为0。
请注意,优先级语义还没有得到充实,并且可能会发生几乎确定的更改。
- $w->调用($revents)
-
使用给定的事件掩码立即调用回调。
- $w->feed_event($revents)
-
将此观察者的一些事件输入EV。EV将对此调用作出反应,就像观察者收到给定的$复仇
面具。
- $revents=$w->清除挂起
-
如果观察程序处于挂起状态,此函数将清除其挂起状态并返回其$复仇
位集(就像调用了它的回调一样)。如果观察程序没有挂起,它什么也不做并返回0
.
- $previous_state=$w->keepalive($bool)
-
通常情况下,EV::运行
将在没有活动观察程序时返回(这是一个“死锁”,因为无法再取得任何进展)。这很方便,因为它可以让你启动你的观察者(和你的工作),打电话EV::运行
当它返回时,您知道您的所有作业都已完成(或者他们忘记为任务注册一些观察者:)。
然而,有时这会妨碍您,例如当调用EV::运行
(通常是主程序)与长寿观察程序不是同一个模块(例如,甚至是其他人编写的DNS客户端模块)。然后,您可能希望处理任何未完成的请求,但不希望保留EV::运行
因为您碰巧有这个长时间运行的UDP端口观察程序,所以不会返回。
在这种情况下,您可以清除keepalive状态,这意味着即使您的观察程序处于活动状态,它也不会保持EV::运行
从返回。
keepalive的初始值为true(enabled),您可以随时更改它。
示例:为某些UDP套接字注册I/O观察程序,但不要仅仅因为该观察程序而阻止事件循环运行。
my$udp_socket=。。。my$udp_watcher=EV::io$udp_socket,EV::READ,sub{…};$udp_watcher->keepalive(0);
- $loop=$w->循环
-
返回此观察程序附加到的循环。
守望者类型
以下各小节描述了单个观察者类型。
I/O WATCHERS-这个文件描述符可读写吗?
- $w=EV::io$fileno_or_fh,$eventmask,$callback
-
- $w=EV::io_ns$fileno_or_fh,$eventmask,$callback
-
- $w=$loop->io($fileno_or_fh,$eventmask,$callback)
-
- $w=$loop->io_ns($fileno_or_fh、$eventmask、$callback)
-
只要返回的观察程序对象是活动的,就调用$回调
当中指定了至少一个事件时$事件掩码
发生。
$eventmask可以是这些常量中的一个或多个,或将其组合在一起:
EV::READ等待READ()不再阻塞EV::WRITE等待WRITE()不再阻塞
这个io(_N)
variant不会启动(激活)新创建的观察程序。
- $w->集合($fileno_or_fh,$eventmask)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $current_fh=$w->fh
-
- $old_fh=$w->fh($new_fh)
-
返回以前设置的文件句柄,并可以选择设置一个新的文件句柄。
- $current_eventmask=$w->事件
-
- $old_eventmask=$w->事件($new_eventmak)
-
返回以前设置的事件掩码,并可以选择设置新的事件掩码。
计时器计时器-相对和可选重复超时
- $w=EV::计时器$after、$repeat、$callback
-
- $w=EV::timer_ns$之后,$repeat,$callback
-
- $w=$loop->计时器($after、$repeat、$callback)
-
- $w=$loop->timer_ns($after、$repeat、$callback)
-
在之后调用回调之后$
秒(可以是分数或负数)。如果$重复
非零,则在回调返回后,计时器将重新启动($repeat值为$after)。
这意味着回调将在之后$
秒,然后每隔$重复
秒。计时器尽其所能不漂移,但它调用计时器的频率不会高于每次事件循环迭代一次,在其他情况下可能会漂移。如果这是不可接受的,那么看看EV::periodical,它可以提供长期稳定的定时器。
计时器基于一个单调的时钟,也就是说,如果有人在计时器运行时坐在机器前面并更改系统时钟,那么计时器将(大致)以相同的时间运行。
这个计时器_ns
variant不会启动(激活)新创建的观察程序。
- $w->集合($after,$repeat=0)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $w->再次
-
- $w->再次($repeat)
-
类似于开始
方法,但具有重复计时器的特殊语义:
如果计时器处于活动状态且不重复,它将被停止。
如果计时器处于活动状态并重复,则将超时重置为发生$重复
几秒钟后。
如果计时器处于非活动状态并重复,请使用重复值启动它。
否则什么也不做。
当某些IO操作超时时,此行为很有用。为创建一个具有相同值的计时器对象之后$
和$重复
,然后在读/写观察程序中运行再一次
方法。
如果调用时使用$重复
参数,然后它使用这个计时器重复值。
- $after=$w->剩余
-
计算并返回计时器启动前的剩余时间。
- $repeat=$w->重复
-
- $old_repeat=$w->重复($new_repeate)
-
返回repeat属性的当前值,并可以选择设置一个新值。设置新的值不会重新启动观察程序-如果观察程序处于活动状态,则每当下次过期时都会使用新的重复值。
周期性监视程序-到cron还是不到cron?
- $w=EV::周期性$at,$interval,$rescheme_cb,$callback
-
- $w=EV::periodic_ns$at,$interval,$reschedule_cb,$callback
-
- $w=$loop->periodic($at,$interval,$reschedule_cb,$callback)
-
- $w=$loop->periodic_ns($at,$interval,$reschedule_cb,$callback)
-
与EV::计时器类似,但不是基于相对超时,而是基于绝对时间。除了创建“在”指定时间触发的“简单”计时器外,它还可以用于非漂移绝对计时器和不受时间跳跃不利影响的更复杂、类似cron的设置(即,当系统时钟被显式日期s或其他方式(如ntpd)更改时)。它也是电动汽车中最复杂的观察者类型。
它有三种不同的“模式”:
绝对计时器($interval=$rescheme_cb=0)
这次只需在挂钟时间点火美元于
而且不会重复。当发生时间跳跃时,它不会进行调整,也就是说,如果它将在2011年1月1日运行,那么它将在系统时间达到或超过此时间时运行。
重复间隔计时器($interval>0,$reschedule_cb=0)
在这种模式下,观察者总是被安排在下一次超时$at+N*$间隔
时间(对于最小的整数N),然后重复,而不考虑任何时间跳跃。注意,由于N个
可以是负数,第一次触发可能发生在美元于
.
这可用于创建不随系统时间漂移的计时器:
my$hourly=EV::周期性0,3600,0,sub{打印“一次/小时\n”};
这并不意味着触发器之间总是有3600秒的间隔,但只有当系统时间显示完整小时(UTC)时才会调用回调。
另一种思考方式(对于数学倾向的人来说)是,EV::periodical将尝试在下一个可能的时间以这种模式运行回调$time=$at(mod$interval)
,不考虑任何时间跳跃。
手动重新调度模式($reschedule_cb=coderef)
在此模式下,$interval和$at都将被忽略。相反,每次周期性观察程序被调度时,都会以观察程序作为第一个参数,以当前时间作为第二个参数调用重新调度回调($reschedule_cb)。
此回调永远不能停止或破坏此或任何其他定期观察程序,也不能调用任何事件循环函数或方法。如果需要停止,请返回1e30,然后停止。您可以创建并启动EV::准备
此任务的观察者。
它必须根据传递的时间值(即大于或等于第二个参数的最小时间值)返回下一次触发的时间。它通常会在触发回调之前调用,但也可能在其他时间调用。
这可以用于创建非常复杂的计时器,例如在每个午夜、本地时间(实际上是最后一个午夜之后的一天,以保持示例简单)触发的计时器:
my$daily=EV::周期0,0,sub{my($w,$现在)=@_;使用时间::本地();my(undef、undef和undef,$d、$m和$y)=本地时间$现在;时间::本地::timelocal_nocheck 0、0、0,$d+1、$m、$y},子{打印“现在是午夜或可能很快之后”;};
这个周期_ns
variant不会启动(激活)新创建的观察程序。
- $w->集合($at、$interval、$reschedule_cb)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $w->再次
-
只需再次停止并启动观察程序。
- $time=$w->时间
-
返回预期观察程序下次触发的时间。
- $offset=$w->偏移
-
- $old_offset=$w->偏移量($new_offset)
-
返回偏移量属性的当前值,并可以选择设置新值。设置新值不会重新启动观测器-如果观测器处于活动状态,则在下次过期时使用新的偏移值。
- $interval=$w->interval
-
- $old_interval=$w->间隔($new_interval)
-
有关间隔属性,请参见上文。
- $rescheme_cb=$w->rescheme_cb
-
- $old_reschedule_cb=$w->重新调度_cb($new_reschedule_cb)
-
有关重新安排回调,请参见上文。
信号观测器-当信号发出时,给我发信号!
- $w=EV::信号$signal,$callback
-
- $w=EV::signal_ns$signal,$callback
-
- $w=$loop->信号($signal,$callback)
-
- $w=$loop->signal_ns($signal,$callback)
-
当接收到$信号时调用回调(信号可以通过数字或名称指定,就像杀死
或%SIG公司
).
只有一个事件循环可以捕获给定的信号-试图从两个EV循环捕获相同的信号将立即导致程序崩溃或导致数据损坏。
当您启动信号观测器时,EV将获取进程的信号(内核一次只允许一个组件接收信号),并在您停止它时再次将其删除。当您向%SIG公司
,所以小心。
每个信号可以有任意多个信号观测器。
这个信号_ns
variant不会启动(激活)新创建的观察程序。
- $w->设置($signal)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $current_signum=$w->信号
-
- $old_signum=$w->信号($new_signal)
-
返回先前设置的信号(始终作为数字而非名称),并可选择设置一个新信号。
儿童看护员-注意过程状态的变化
- $w=EV::child$pid、$trace、$callback
-
- $w=EV::child_ns$pid、$trace、$callback
-
- $w=$loop->child($pid、$trace、$callback)
-
- $w=$loop->child_ns($pid、$trace、$callback)
-
当pid的状态更改时调用回调$pid
(或任何pid,如果$pid
为0)(当进程终止或终止时,或者当跟踪为真时,当它停止或继续时,会发生状态更改)。更准确地说:当进程收到SIGCHLD公司
,EV将获取所有已更改/僵尸子级的未完成退出/等待状态,并调用回调。
在子级退出后但在事件循环开始其下一次迭代之前(例如,首先您叉
,则新的子进程可能会退出,只有这样,您才能在新pid的父进程中安装一个子观察程序)。
您可以使用rstatus公司
和rpid公司
watcher对象上的方法。
每个pid可以有任意多个pid观察程序,它们都会被调用。
这个子项(_N)
variant不会启动(激活)新创建的观察程序。
- $w->设置($pid,$trace)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $current_pid=$w->pid
-
返回先前设置的进程id,并可以选择设置一个新的进程id。
- $exit_status=$w->rstatus
-
返回exit/wait状态(如waitpid所返回的,请参阅perlfunc中的waitpid条目)。
- $pid=$w->rpid
-
返回等待的子进程的pid(当您为所有pid安装了观察程序时很有用)。
- EV::Child::reinit[实验]
-
在内部,libev为SIGCHLD公司
不幸的是,很多Perl代码都像本地$SIG{CHLD}
,不幸的是,它已损坏,无法恢复信号处理程序。
如果发生这种情况,可以调用此函数来停止/重新启动内部libev观察器,这将重置信号处理程序。
请注意,这是一个实验函数,其接口可能会更改。
STAT WATCHERS-文件属性刚刚改变了吗?
- $w=EV::stat$path,$interval,$callback
-
- $w=EV::stat_ns$path,$interval,$callback
-
- $w=$loop->stat($path、$interval、$callback)
-
- $w=$loop->stat_ns($path、$interval、$callback)
-
在上检测到文件状态更改时调用回调$路径
. The$路径
不需要存在,从“path exists”更改为“path does not exist”与其他任何更改一样都是一种状态更改。
这个$间隔
对于不存在或不支持OS支持的更改通知的系统,建议使用轮询间隔。如果您使用0
然后使用未指定的默认值(强烈建议使用!),预计通常为5秒左右。
这种观察者类型并不适合大量的统计观察者,因为即使有支持操作系统的更改通知,这也可能是资源密集型的。
这个状态_ns
variant不会启动(激活)新创建的观察程序。
- …=$w->统计
-
这个调用与perl非常相似统计
内置:It统计(使用lstat卫星
)watcher中指定的路径,并将perls stat缓存(以及EV对当前stat值的想法)设置为找到的值。
在标量上下文中,返回一个布尔值表示stat的成功或失败。在列表上下文中,与stat返回相同的13值列表(除了blksize和blocks字段不可靠之外)。
如果出现错误,errno设置为ENOENT公司
(无论实际误差值如何)和nlink链接
值被强制为零(如果stat成功,则nlink保证为非零)。
有关更多信息,请参阅下面的两个条目。
- …=$w->属性
-
就像这样$w->状态
,但没有初始状态:这将返回EV最近检测到的值。有关更多信息,请参阅下一项。
- …=$w->上一个
-
就像这样$w->状态
,但没有初始stat'ing:这将返回更改之前的一组值。
也就是说,当调用观察程序回调时,$w->以前
将设置为找到的值之前检测到更改,而$w->属性
返回发现的导致更改检测的值。两者之间的差异(如果有)上一个
和属性
是什么触发了回调。
如果您对文件系统对象做了一些操作,并且不想触发另一个更改,可以调用统计
更新EV对当前属性的想法。
- $w->集合($path,$interval)
-
重新配置观察程序,有关详细信息,请参阅上面的构造函数。可以随时拨打。
- $current_path=$w->路径
-
- $old_path=$w->路径($new_path)
-
返回以前设置的路径,并可以选择设置一个新路径。
- $current_interval=$w->间隔
-
- $old_interval=$w->间隔($new_interval)
-
返回以前设置的间隔,并可以选择设置新的间隔。可用于查询实际使用的间隔。
空闲观察者-当你没有更好的事情要做时。。。
- $w=EV::空闲$回调
-
- $w=EV::idle_ns$回调
-
- $w=$loop->空闲($callback)
-
- $w=$loop->idle_ns($callback)
-
当没有其他具有相同或更高优先级的挂起观察程序时,调用回调(当然,不包括检查、准备和其他优先级相同或更低的空闲观察程序)。它们被称为空闲观察程序,因为当观察程序是流程中优先级最高的挂起事件时,流程将被视为处于该优先级的空闲状态。
如果你想要一个只有在不其他活动尚未完成,您必须设置优先级EV::明尼苏达州
.
只要有空闲观察程序处于活动状态,进程就不会阻塞,并且会反复调用它们,直到停止为止。
例如,如果您的优先级为空闲观察程序0
和1
,并优先使用I/O观察程序0
,然后优先使用空闲观察程序1
I/O观察程序将始终在准备就绪时运行。仅当空闲观察程序处于优先级时1
已停止,I/O观察程序处于优先级0
未与挂起0
-调用优先级空闲观察程序。
这个空闲_ns
variant不会启动(激活)新创建的观察程序。
准备观察家-定制您的活动循环!
- $w=EV::准备$回调
-
- $w=EV::prepare_ns$回调
-
- $w=$loop->准备($callback)
-
- $w=$loop->prepare_ns($callback)
-
在进程阻塞之前调用回调。此时您仍然可以创建/修改任何观察程序。
有关解释和示例,请参阅下面的EV::check watcher。
这个prepare_ns(准备_秒)
variant不会启动(激活)新创建的观察程序。
CHECK WATCHERS-定制更多事件循环!
- $w=EV::检查$callback
-
- $w=EV::check_ns$回调
-
- $w=$loop->检查($callback)
-
- $w=$loop->check_ns($callback)
-
在进程再次唤醒后(在收集事件后)调用回调,但在调用任何其他回调之前。
这可以用于将其他基于事件的软件集成到EV主循环中:您注册一个准备回调,然后在其中创建其他软件所需的io和计时器观测器。下面是集成Net::SNMP的真实示例(省略了一些详细信息):
我们的@snmp_watcher;我们的$snmp_prepare=EV::prepare sub{#除非处于活动状态,否则不执行任何操作$dispatcher->{_event_queue_h}或返回;#让调度员处理任何未完成的工作…未显示#为每个套接字创建I/O观察程序@snmp_watcher=((映射{EV::io$_,EV::READ,子{}}键%{$dispatcher->{_descriptors}}),EV::计时器+($event->[Net::SNMP::Dispatcher::_ACTIVE]? $事件->[Net::SNMP::Dispatcher::_TIME]-EV::now:0),0,子{},);};
回调是不相关的(甚至没有被调用),这些观察程序的唯一目的是在其中一个事件发生(套接字可读或计时器超时)时立即唤醒进程。相应的EV::check watcher随后将清理:
我们的$snmp_check=EV::check子{#摧毁所有观察者@snmp_watcher=();#让调度员处理任何新事物…未显示};
创建的观察程序的回调不会被调用,因为观察程序在这之前就被销毁了(记住EV::check首先被调用)。
这个选中(_N)
variant不会启动(激活)新创建的观察程序。
- EV::检查持续问题
-
与所有其他观察程序类型一样,有一个位掩码常量用于$复仇
和其他地方。这个EV::检查
是特殊的,因为它与检查
Perl调用了sub。这不会对较新的perl(从5.8.9开始)造成大问题,但这意味着常数必须是内联,即运行时调用将不起作用。这意味着只要您始终使用EV
然后EV::检查
你是安全的。
FORK WATCHERS-在FORK之后恢复事件循环的大胆行为
当叉()
检测到。调用在事件循环接下来和之前阻塞之前完成检查
守望者被叫来了,而且只有在叉子后面的孩子。
- $w=EV::fork$回调
-
- $w=EV::fork_ns$回调
-
- $w=$loop->fork($callback)
-
- $w=$loop->fork_ns($callback)
-
在fork之后的子进程中恢复事件循环之前调用回调。
这个分叉(_N)
variant不会启动(激活)新创建的观察程序。
嵌入式监视程序-当一个后端不够时。。。
这是一种相当高级的观察程序类型,允许您将一个事件循环嵌入到另一个事件环中(嵌入式循环中当前仅支持IO事件,其他类型的观察程序可能会以延迟或不正确的方式处理,因此不能使用)。
请参阅libev文档,网址为http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_embed_code_when_one_backend_(本地安装为电动汽车::libev)了解更多详细信息。
简而言之,此观察器在BSD系统上最有用,因为它不工作kqueue,所以仍然能够处理大量套接字:
我的$socket_loop;#检查是否支持使用SELECT或POLL _and_ KQUEUE如果((EV::backend&(EV::backend_POLL | EV::backend_SELECT))&&(EV::supported_backends&EV::embeddable_backenders&EV::BACKEND_KQUEUE)) {#对套接字使用kqueue$socket_loop=新EV::环路EV::BACKEND_KQUEUE | EV::FLAG_NOENV;}#否则使用默认循环$socket_loop | |=EV::default_loop;
- $w=EV::嵌入$otherloop[,$callback]
-
- $w=EV::embed_ns$otherloop[,$callback]
-
- $w=$loop->嵌入($otherloop[,$callback])
-
- $w=$loop->embed_ns($otherloop[,$callback])
-
嵌入式事件循环时调用回调($其他回路
)具有任何I/O活动。这个$回调
是可选的:如果它丢失了,那么嵌入式事件循环将被自动管理(建议这样做),否则您必须调用打扫
你自己。
这个嵌入_个
variant不会启动(激活)新创建的观察程序。
ASYNC WATCHERS-如何唤醒另一个事件循环
异步观察程序由EV提供,但在perl中几乎没有直接使用,因为perl既不支持并行运行的线程,也不支持直接访问信号处理程序或其他可能有价值的上下文。
然而,可以从XS级别使用它们。
有关详细信息,请参阅libev文档。
- $w=EV::async$回调
-
- $w=EV::async_ns$回调
-
- $w=$loop->async($callback)
-
- $w=$loop->async_ns($callback)
-
- $w->发送
-
- $bool=$w->async_pending
-
CLEANUP WATCHERS-如何在事件循环结束时进行清理
Perl级别不支持清理观察程序,目前只能通过XS使用。
PERL信号
Perl信号处理时(%SIG公司
)不受EV的影响,EV的行为与任何其他C库相同:只有在Perl运行时才会处理Perl信号,这意味着只有在下次调用事件回调时才会调用信号处理程序。
解决方案是使用电动汽车信号观测器(参见EV::信号
),这将确保对其他事件观察者进行适当操作。
如果由于任何原因无法执行此操作,还可以通过安装EV::检查
观察者:
my$async_check=EV::check-sub{};
这可以确保perl在短时间内得到控制,以处理任何挂起的信号,还可以确保(稍微)降低总体操作速度。
ITHREADS公司
此模块无论如何都不支持Ithreads。Perl伪线程是邪恶的东西,必须消亡。完全支持Coro提供的真实线程(并且可以通过以下方式获得增强支持Coro::EV).
叉子
现代操作系统的大多数“改进”的事件传递机制在fork(2)方面都有不少问题(坦率地说:它不受支持,通常具有破坏性)。Libev提供了一个函数,该函数在子级中分叉后重新创建内核状态,从而可以解决这个问题。
在非win32平台上,此模块需要pthread_atfork功能来自动为您执行此操作。不过,这个函数在大多数BSD上都有很大的缺陷,所以YMMV也是如此。这样做的开销可以忽略不计,因为函数当前所做的一切都是设置一个标记,只有在下次使用事件循环时才会检查该标记,所以当您使用fork但不使用EV时,开销是最小的。
在win32上,没有fork的概念,所以这一切当然都不适用。
另请参阅
EV::MakeMaker-XS API的MakeMaker接口,EV::ADNS(异步DNS),闪光::EV(使Glib/Gtk2使用EV作为事件循环),企业价值::Glib(将Glib嵌入EV),Coro::EV(高效线程集成),网络::SNMP::EV(异步SNMP),任何事件用于事件无关和可移植的事件驱动编程。
作者
马克·莱曼<schmorp@schmorp.de>http://home.schmorp.de/