logo资料库

libev手册.pdf

第1页 / 共129页
第2页 / 共129页
第3页 / 共129页
第4页 / 共129页
第5页 / 共129页
第6页 / 共129页
第7页 / 共129页
第8页 / 共129页
资料共129页,剩余部分请下载后查看
简介:
NAME名字
SYNOPSIS概要
EXAMPLE PROGRAM示例程序
ABOUT THIS DOCUMENT 关于文档
WHAT TO READ WHEN IN A HURRY 快速阅读
ABOUT LIBEV 关于libev
FEATURES 特点
CONVENTIONS 约定
TIME REPRESENTATION 时间描述
ERROR HANDLING 错误处理
GLOBAL FUNCTIONS 全局函数
ev_tstamp ev_time ()
ev_sleep (ev_tstamp interval)
int ev_version_major ()
int ev_version_minor ()
unsigned int ev_supported_backends ()
unsigned int ev_recommended_backends ()
unsigned int ev_embeddable_backends ()
ev_set_allocator (void *(*cb)(void *ptr, long size
ev_set_syserr_cb (void (*cb)(const char *msg))
ev_feed_signal (int signum)
FUNCTIONS CONTROLLING EVENT LOOPS
struct ev_loop *ev_default_loop (unsigned int flag
struct ev_loop *ev_loop_new (unsigned int flags)
EVFLAG_AUTO
EVFLAG_NOENV
EVFLAG_FORKCHECK
EVFLAG_NOINOTIFY
EVFLAG_SIGNALFD
EVFLAG_NOSIGMASK
EVBACKEND_SELECT (value 1, portable select backend
EVBACKEND_POLL (value 2, poll backend, available e
EVBACKEND_EPOLL (value 4, Linux)
EVBACKEND_KQUEUE (value 8, most BSD clones)
EVBACKEND_DEVPOLL (value 16, Solaris 8)
EVBACKEND_PORT (value 32, Solaris 10)
EVBACKEND_ALL
EVBACKEND_MASK
ev_loop_destroy (loop)
ev_loop_fork (loop)
int ev_is_default_loop (loop)
unsigned int ev_iteration (loop)
unsigned int ev_depth (loop)
unsigned int ev_backend (loop)
ev_tstamp ev_now (loop)
ev_now_update (loop)
ev_suspend (loop)
ev_resume (loop)
ev_run (loop, int flags)
ev_break (loop, how)
ev_ref (loop)
ev_unref (loop)
ev_set_io_collect_interval (loop, ev_tstamp interv
ev_set_timeout_collect_interval (loop, ev_tstamp i
ev_invoke_pending (loop)
int ev_pending_count (loop)
ev_set_invoke_pending_cb (loop, void (*invoke_pend
ev_set_loop_release_cb (loop, void (*release)(EV_P
ev_set_userdata (loop, void *data)
void *ev_userdata (loop)
ev_verify (loop)
ANATOMY OF A WATCHER
EV_READ
EV_WRITE
EV_TIMER
EV_PERIODIC
EV_SIGNAL
EV_CHILD
EV_STAT
EV_IDLE
EV_PREPARE
EV_CHECK
EV_EMBED
EV_FORK
EV_CLEANUP
EV_ASYNC
EV_CUSTOM
EV_ERROR
GENERIC WATCHER FUNCTIONS
ev_init (ev_TYPE *watcher, callback)
ev_TYPE_set (ev_TYPE *watcher, [args])
ev_TYPE_init (ev_TYPE *watcher, callback, [args])
ev_TYPE_start (loop, ev_TYPE *watcher)
ev_TYPE_stop (loop, ev_TYPE *watcher)
bool ev_is_active (ev_TYPE *watcher)
bool ev_is_pending (ev_TYPE *watcher)
callback ev_cb (ev_TYPE *watcher)
ev_cb_set (ev_TYPE *watcher, callback)
ev_set_priority (ev_TYPE *watcher, int priority)
int ev_priority (ev_TYPE *watcher)
ev_invoke (loop, ev_TYPE *watcher, int revents)
int ev_clear_pending (loop, ev_TYPE *watcher)
ev_feed_event (loop, ev_TYPE *watcher, int revents
WATCHER STATES
initialiased
started/running/active
pending
stopped
WATCHER PRIORITY MODELS
WATCHER TYPES
ev_io - is this file descriptor readable or writab
The special problem of disappearing file descripto
The special problem of dup'ed file descriptors
The special problem of files
The special problem of fork
The special problem of SIGPIPE
The special problem of accept()ing when you can't
Watcher-Specific Functions
ev_io_init (ev_io *, callback, int fd, int events)
ev_io_set (ev_io *, int fd, int events)
int fd [read-only]
int events [read-only]
Examples
ev_timer - relative and optionally repeating timeo
Be smart about timeouts
1. Use a timer and stop, reinitialise and start it
2. Use a timer and re-start it with ev_timer_again
3. Let the timer time out, but then re-arm it as r
4. Wee, just use a double-linked list for your tim
The special problem of being too early
The special problem of time updates
The special problem of unsynchronised clocks
The special problems of suspended animation
Watcher-Specific Functions and Data Members
ev_timer_init (ev_timer *, callback, ev_tstamp aft
ev_timer_set (ev_timer *, ev_tstamp after, ev_tsta
ev_timer_again (loop, ev_timer *)
ev_tstamp ev_timer_remaining (loop, ev_timer *)
ev_tstamp repeat [read-write]
Examples
ev_periodic - to cron or not to cron?
Watcher-Specific Functions and Data Members
ev_periodic_init (ev_periodic *, callback, ev_tsta
ev_periodic_set (ev_periodic *, ev_tstamp offset,
* absolute timer (offset = absolute time, interval
* repeating interval timer (offset = offset within
* manual reschedule mode (offset ignored, interval
ev_periodic_again (loop, ev_periodic *)
ev_tstamp ev_periodic_at (ev_periodic *)
ev_tstamp offset [read-write]
ev_tstamp interval [read-write]
ev_tstamp (*reschedule_cb)(ev_periodic *w, ev_tsta
Examples
ev_signal - signal me when a signal gets signalled
The special problem of inheritance over fork/execv
The special problem of threads signal handling
Watcher-Specific Functions and Data Members
ev_signal_init (ev_signal *, callback, int signum)
ev_signal_set (ev_signal *, int signum)
int signum [read-only]
Examples
ev_child - watch out for process status changes
Process Interaction
Overriding the Built-In Processing
Stopping the Child Watcher
Watcher-Specific Functions and Data Members
ev_child_init (ev_child *, callback, int pid, int
ev_child_set (ev_child *, int pid, int trace)
int pid [read-only]
int rpid [read-write]
int rstatus [read-write]
Examples
ev_stat - did the file attributes just change?
ABI Issues (Largefile Support)
Inotify and Kqueue
stat () is a synchronous operation
The special problem of stat time resolution
Watcher-Specific Functions and Data Members
ev_stat_init (ev_stat *, callback, const char *pat
ev_stat_set (ev_stat *, const char *path, ev_tstam
ev_stat_stat (loop, ev_stat *)
ev_statdata attr [read-only]
ev_statdata prev [read-only]
ev_tstamp interval [read-only]
const char *path [read-only]
Examples
ev_idle - when you've got nothing better to do...
Watcher-Specific Functions and Data Members
ev_idle_init (ev_idle *, callback)
Examples
ev_prepare and ev_check - customise your event loo
Watcher-Specific Functions and Data Members
ev_prepare_init (ev_prepare *, callback)
ev_check_init (ev_check *, callback)
Examples
ev_embed - when one backend isn't enough...
ev_embed and fork
Watcher-Specific Functions and Data Members
ev_embed_init (ev_embed *, callback, struct ev_loo
ev_embed_set (ev_embed *, callback, struct ev_loop
ev_embed_sweep (loop, ev_embed *)
struct ev_loop *other [read-only]
Examples
ev_fork - the audacity to resume the event loop af
The special problem of life after fork - how is it
Watcher-Specific Functions and Data Members
ev_fork_init (ev_fork *, callback)
ev_cleanup - even the best things end
Watcher-Specific Functions and Data Members
ev_cleanup_init (ev_cleanup *, callback)
ev_async - how to wake up an event loop
Queueing
queueing from a signal handler context
queueing from a thread context
Watcher-Specific Functions and Data Members
ev_async_init (ev_async *, callback)
ev_async_send (loop, ev_async *)
bool = ev_async_pending (ev_async *)
OTHER FUNCTIONS
ev_once (loop, int fd, int events, ev_tstamp timeo
ev_feed_fd_event (loop, int fd, int revents)
ev_feed_signal_event (loop, int signum)
COMMON OR USEFUL IDIOMS (OR BOTH)
ASSOCIATING CUSTOM DATA WITH A WATCHER
BUILDING YOUR OWN COMPOSITE WATCHERS
MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDI
THREAD LOCKING EXAMPLE
THREADS, COROUTINES, CONTINUATIONS, QUEUES... INST
LIBEVENT EMULATION
C++ SUPPORT
ev::READ, ev::WRITE etc.
ev::tstamp, ev::now
ev::io, ev::timer, ev::periodic, ev::idle, ev::sig
ev::TYPE::TYPE ()
ev::TYPE::TYPE (loop)
ev::TYPE::~TYPE
w->set (object *)
w->set (object *)
w->set (void *data = 0)
w->set (loop)
w->set ([arguments])
w->start ()
w->start ([arguments])
w->stop ()
w->again () (ev::timer, ev::periodic only)
w->sweep () (ev::embed only)
w->update () (ev::stat only)
OTHER LANGUAGE BINDINGS
Perl
Python
Ruby
Haskell
D
Ocaml
Lua
MACRO MAGIC
EV_A, EV_A_
EV_P, EV_P_
EV_DEFAULT, EV_DEFAULT_
EV_DEFAULT_UC, EV_DEFAULT_UC_
EMBEDDING
FILESETS
CORE EVENT LOOP
LIBEVENT COMPATIBILITY API
AUTOCONF SUPPORT
PREPROCESSOR SYMBOLS/MACROS
EV_COMPAT3 (h)
EV_STANDALONE (h)
EV_USE_FLOOR
EV_USE_MONOTONIC
EV_USE_REALTIME
EV_USE_CLOCK_SYSCALL
EV_USE_NANOSLEEP
EV_USE_EVENTFD
EV_USE_SELECT
EV_SELECT_USE_FD_SET
EV_SELECT_IS_WINSOCKET
EV_FD_TO_WIN32_HANDLE(fd)
EV_WIN32_HANDLE_TO_FD(handle)
EV_WIN32_CLOSE_FD(fd)
EV_USE_POLL
EV_USE_EPOLL
EV_USE_KQUEUE
EV_USE_PORT
EV_USE_DEVPOLL
EV_USE_INOTIFY
EV_ATOMIC_T
EV_H (h)
EV_CONFIG_H (h)
EV_EVENT_H (h)
EV_PROTOTYPES (h)
EV_MULTIPLICITY
EV_MINPRI
EV_MAXPRI
EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABL
EV_FEATURES
1 - faster/larger code
2 - faster/larger data structures
4 - full API configuration
8 - full API
16 - enable all optional watcher types
32 - enable all backends
64 - enable OS-specific "helper" APIs
EV_AVOID_STDIO
EV_NSIG
EV_PID_HASHSIZE
EV_INOTIFY_HASHSIZE
EV_USE_4HEAP
EV_HEAP_CACHE_AT
EV_VERIFY
EV_COMMON
EV_CB_DECLARE (type)
EV_CB_INVOKE (watcher, revents)
ev_set_cb (ev, cb)
EXPORTED API SYMBOLS
EXAMPLES
INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE
THREADS AND COROUTINES
THREADS
* most applications have a main thread: use the de
* one loop per thread is usually a good model.
* other models exist, such as the leader/follower
* often you need to talk to some other thread whic
COROUTINES
COMPILER WARNINGS
VALGRIND
PORTABILITY NOTES
GNU/LINUX 32 BIT LIMITATIONS
OS/X AND DARWIN BUGS
kqueue is buggy
poll is buggy
select is buggy
SOLARIS PROBLEMS AND WORKAROUNDS
errno reentrancy
Event port backend
AIX POLL BUG
WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS
General issues
The winsocket select function
Limited number of file descriptors
PORTABILITY REQUIREMENTS
void (*)(ev_watcher_type *, int revents) must have
pointer accesses must be thread-atomic
sig_atomic_t volatile must be thread-atomic as wel
sigprocmask must work in a threaded environment
long must be large enough for common memory alloca
double must hold a time value in seconds with enou
ALGORITHMIC COMPLEXITIES
Starting and stopping timer/periodic watchers: O(l
Changing timer/periodic watchers (by autorepeat or
Starting io/check/prepare/idle/signal/child/fork/a
Stopping check/prepare/idle/fork/async watchers: O
Stopping an io/signal/child watcher: O(number_of_w
Finding the next timer in each loop iteration: O(1
Each change on a file descriptor per loop iteratio
Activating one watcher (putting it into the pendin
Priority handling: O(number_of_priorities)
Sending an ev_async: O(1)
Processing ev_async_send: O(number_of_async_watche
Processing signals: O(max_signal_number)
PORTING FROM LIBEV 3.X TO 4.X
EV_COMPAT3 backwards compatibility mechanism
ev_default_destroy and ev_default_fork have been r
function/symbol renames
EV_MINIMAL mechanism replaced by EV_FEATURES
GLOSSARY
active
application
backend
callback
callback/watcher invocation
event
event library
event loop
event model
pending
real time
wall-clock time
watcher
AUTHOR
简介: libev 是高性能事件循环/事件模型的网络库,并且包含大量新特性。 它是继 lievent 和 Event perl module 之后的一套全新网络库。它追求的目标: 速度更快,bug 更少,特性更多,体积更小。 它和 libevent 很像,按照作者的介绍,可以作为 libevent 的替代者,能够提供 更高的性能。并不需要复杂的配置。 希望它的出现,能为高性能网络应用注入新鲜血液。 它的出现真是应了那句:很快,很强大。 NAME 名字 libev - a high performance full-featured event loop written in C libev - 用 C 写的高性能多功能事件循环库 SYNOPSIS 概要 #include EXAMPLE PROGRAM 示例程序 // a single header file is required //需要一个特定的头文件 #include #include // for puts 为了输出结果 // every watcher type has its own typedef'd struct // with the name ev_TYPE //每个 watcher 都有用 ev_TYPE 定义的结构体 ev_io stdin_watcher; ev_timer timeout_watcher; // all watcher callbacks have a similar signature //所有 watcher 的回调函数都有相似的特点
// this callback is called when data is readable on stdin //当标准输入上有可读取的数据时,将调用下面这个回调函数 static void stdin_cb (EV_P_ ev_io *w, int revents) { puts ("stdin ready"); // for one-shot events, one must manually stop the watcher // with its corresponding stop function. //每一次事件都必须用对应的停止函数,手动的停止其 watcher ev_io_stop (EV_A_ w); // this causes all nested ev_run's to stop iterating //这将导致所有嵌套执行的 ev_run 停止监听 ev_break (EV_A_ EVBREAK_ALL); } // another callback, this time for a time-out //还有一个回调函数,这是一个定时器回调 static void timeout_cb (EV_P_ ev_timer *w, int revents) { puts ("timeout"); // this causes the innermost ev_run to stop iterating //这将导致最早运行的 ev_run 停止监听 ev_break (EV_A_ EVBREAK_ONE); } int main (void) { // use the default event loop unless you have special needs //除非有特殊需要一般使用默认的事件循环 struct ev_loop *loop = EV_DEFAULT; // initialise an io watcher, then start it //初始化一个 I/Owatcher,然后启动它 // this one will watch for stdin to become readable //这个监听将检测标准输入是否有可读取的数据 ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); ev_io_start (loop, &stdin_watcher); // initialise a timer watcher, then start it //初始化一个定时器 watcher,然后启动它 // simple non-repeating 5.5 second timeout //只有一次,没有重复的 5.5 秒定时
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); ev_timer_start (loop, &timeout_watcher); // now wait for events to arrive //现在等待事件触发 ev_run (loop, 0); // break was called, so exit //已经撤销了监听,所有退出程序 return 0; } ABOUT THIS DOCUMENT 关于文档 This document documents the libev software package. 本手册介绍的是 libev 软件库。 The newest version of this document is also available as an html- formatted web page you might find easier to navigate when reading it for the first time: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod. 本手册最新的版本为 html 格式的 web 页面,你在首次读它的时候更容易浏览: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod While this document tries to be as complete as possible in documenting libev, its usage and the rationale behind its design, it is not a tutorial on event-based programming, nor will it introduce event-based programming with libev. 虽然本手册试图尽可能完整的介绍 libev 的用法和它的设计背后的原理,但是 本手册既不是基于事件编程的教程,也想用 libev 引入基于事件的编程。 Familiarity with event based programming techniques in general is assumed throughout this document. 本手册适合熟悉基于事件的编程技术的人员使用。 WHAT TO READ WHEN IN A HURRY 快速阅读
This manual tries to be very detailed, but unfortunately, this also makes it very long. If you just want to know the basics of libev, I suggest reading ANATOMY OF A WATCHER, then the EXAMPLE PROGRAM above and look up the missing functions in GLOBAL FUNCTIONS and the ev_io and ev_timer sections in WATCHER TYPES. 本手册努力的变得非常详细,因此很不幸的是,这也使本手册变得很长。如果 你只想了解关于 libev 最基础的东西,我建议先阅读《透视一个 WATCHER》, 然后在《示例程序》的基础上,在《全局函数》里查看遇到的函数,在 《WATCHER 分类》里查看 ev_io 和 ev_timer 章节。 ABOUT LIBEV 关于 libev Libev is an event loop: you register interest in certain events (such as a file descriptor being readable or a timeout occurring), and it will manage these event sources and provide your program with events. Libev 是一个事件循环:你注册感兴趣的特定事件(比如一个文件可以读取时 或者发生超时时),它将管理这些事件源,将这些事件反馈给你的程序。 To do this, it must take more or less complete control over your process (or thread) by executing the event loop handler, and will then communicate events via a callback mechanism. 为了实现这些,至少要在你的进程(或线程)中执行事件循环句柄控制,然后 就能通过回调机制进行事件通信 You register interest in certain events by registering so-called event watchers, which are relatively small C structures you initialise with the details of the event, and then hand it over to libev by starting the watcher. 你通过所谓的 watchers 注册感兴趣的特定事件,这些 watchers 都是相对较 小的 C 语言结构体,它们通过初始化具体的事件得到,然后交由 libev 启动那 个 watcher。 FEATURES 特点 Libev supports select, poll, the Linux-specific epoll, the BSD-specific kqueue and the Solaris-specific event port mechanisms for file descriptor events (ev_io), the Linux inotify interface (for ev_stat), Linux eventfd/signalfd (for faster and cleaner inter-thread wakeup (ev_async)/signal handling (ev_signal)) relative timers (ev_timer), absolute timers with customised rescheduling (ev_periodic),
synchronous signals (ev_signal), process status change events (ev_child), and event watchers dealing with the event loop mechanism itself (ev_idle, ev_embed, ev_prepare and ev_check watchers) as well as file watchers (ev_stat) and even limited support for fork events (ev_fork). Libev 支持 select,poll,Linux 特有的 epoll,BSD 特有的 kqueue 以及 Solaris 特有的文件描述符事件端口机制(ev_io),Linux 信息通知接口 (ev_stat),Linux 事件文件/信号文件(为了更快更完整的唤醒沉睡线程 (ev_async)/信号捕捉(ev_signal))相对定时器(ev_timer),用户自 定义的绝对定时器(ev_periodic),同步信号(ev_signal),进程状态改变 事件(ev_child),和通过事件循环机制实现的事件观察者管理本身 (ev_idle,ev_embed,ev_prepare 和 ev_check 监控)也和文件监控 (ev_stat)和有限支持的派生子进程事件(ev_fork)一样。 It also is quite fast (see this benchmark comparing it to libevent for example). 它也更加快速(查看同 libevent 实例对比)。 CONVENTIONS 约定 Libev is very configurable. In this manual the default (and most common) configuration will be described, which supports multiple event loops. For more info about various configuration options please have a look at EMBED section in this manual. If libev was configured without support for multiple event loops, then all functions taking an initial argument of name loop (which is always of type struct ev_loop *) will not have this argument. LIBEV 非常容易配置。本手册介绍了默认的(和最常用的)配置,它适用于大 多数的事件循环。更多的关于各种配置选项请查看本手册中的 EMBED 章节部 分。如果 libev 的配置为不支持大多数的事件循环,则所有的带有初始参数名 loop(通常类型为 struct ev_loop *)的函数将不再有这个参数。 TIME REPRESENTATION 时间描述 Libev represents time as a single floating point number, representing the (fractional) number of seconds since the (POSIX) epoch (in practice somewhere near the beginning of 1970, details are complicated, don't ask). This type is called ev_tstamp, which is what you should use too. It usually aliases to the double type in C. When you need to do any calculations on it, you should treat it as some floating point value.
Libev 描述时间采用一个浮点数,它来自于距离(POSIX)时期的一个(带小 数)的秒数(实践中通常开始于 1970 年附近,具体细节很复杂,不要深究)。 Unlike the name component stamp might indicate, it is also used for time differences (e.g. delays) throughout libev. 不同名称的组件戳可能表明,它在整个 libev 中也用于不同的时间段(比如延 迟)。 ERROR HANDLING 错误处理 Libev knows three classes of errors: operating system errors, usage errors and internal errors (bugs). Libev 知道三类错误:操作系统错误、用法错误和内部错误(bugs) When libev catches an operating system error it cannot handle (for example a system call indicating a condition libev cannot fix), it calls the callback set via ev_set_syserr_cb, which is supposed to fix the problem or abort. The default is to print a diagnostic message and to call abort (). 当 libev 捕捉到无法处理的操作系统错误时(如一个系统调用返回了 libev 不 能识别的返回值),它通过调用 ev_set_syserr_cb 设定的回调函数,它假设 这个回调函数可修正这个问题或者是退出。默认行为是打印一个摘要信息并调 用 abort()。 When libev detects a usage error such as a negative timer interval, then it will print a diagnostic message and abort (via the assert mechanism, so NDEBUG will disable this checking): these are programming errors in the libev caller and need to be fixed there. 当 libev 检测到用法错误(如负的时间),它会打印一条摘要信息并退出(使 用 assert 机制,因此宏 NDEBUG 会关闭这种检测); 表明这里有 libev 调 用端的编程错误需要修正。 Libev also has a few internal error-checking assertions, and also has extensive consistency checking code. These do not trigger under normal circumstances, as they indicate either a bug in libev or worse. Libev 也有一些内部错误检查,也有大多数的代码错误检查。这些在正常情况 下不会触发,他们表明在 libev 存在一个 bug 或者更大的错误。 GLOBAL FUNCTIONS 全局函数
These functions can be called anytime, even before initialising the library in any way. 这些函数可以在任何时候被调用,甚至可以在初始化 libev 库之前调用。 ev_tstamp ev_time () Returns the current time as libev would use it. Please note that the ev_now function is usually faster and also often returns the timestamp you actually want to know. Also interesting is the combination of ev_now_update and ev_now. 返回 libev 使用它时的当前时间。请注意,ev_now 函数通常更快, 也经常用来返回你想知道的时间戳。ev_now_update 和 ev_now 组合在一起使用更好 ev_sleep (ev_tstamp interval) Sleep for the given interval: The current thread will be blocked until either it is interrupted or the given time interval has passed (approximately - it might return a bit earlier even if not interrupted). Returns immediately if interval <= 0. 休眠指定的时间间隔:当前线程将被阻塞直到它被中断或者给定的 时间间隔已经过去(近视值-即使没有中断它也会返回的早一点)。 当 interval <= 0.时将立即返回 Basically this is a sub-second-resolution sleep (). 基本上这是一个精度稍低的 sleep()函数 The range of the interval is limited - libev only guarantees to work with sleep times of up to one day (interval <= 86400). Interval 的值是有限制的-libev 只保证休眠时间最长为一天 (interval <= 86400) int ev_version_major () int ev_version_minor () You can find out the major and minor ABI version numbers of the library you linked against by calling the functions ev_version_major and ev_version_minor. If you
want, you can compare against the global symbols EV_VERSION_MAJOR and EV_VERSION_MINOR, which specify the version of the library your program was compiled against. 通过调用 ev_version_major 和 ev_version_minor 函数,你可 以找出主要的和次要的 ABI 链接库版本号。如果需要,你可以比较 全局字段 EV_VERSION_MAJOR 和 EV_VERSION_MINOR,它 们表明了你的程序编译完成后的库版本。 These version numbers refer to the ABI version of the library, not the release version. 这些版本号只是关于 ABI 库版本号,不是发布的版本号。 Usually, it's a good idea to terminate if the major versions mismatch, as this indicates an incompatible change. Minor versions are usually compatible to older versions, so a larger minor version alone is usually not a problem. Example: Make sure we haven't accidentally been linked against the wrong version (note, however, that this will not detect other ABI mismatches, such as LFS or reentrancy). assert (("libev version mismatch", ev_version_major () == EV_VERSION_MAJOR && ev_version_minor () >= EV_VERSION_MINOR)); unsigned int ev_supported_backends () Return the set of all backends (i.e. their corresponding EV_BACKEND_* value) compiled into this binary of libev (independent of their availability on the system you are running on). See ev_default_loop for a description of the set values. Example: make sure we have the epoll method, because yeah this is cool and a must have and can we have a torrent of it please!!!11 assert (("sorry, no epoll, no sex", ev_supported_backends () & EVBACKEND_EPOLL));
分享到:
收藏