名称
zmq_ppoll - 带信号掩码的输入/输出多路复用
概要
int zmq_ppoll (zmq_pollitem_t '*items', int 'nitems', long 'timeout', const sigset_t '*sigmask');
说明
zmq_poll() 和 zmq_ppoll() 之间的关系类似于 poll(2) 和 ppoll(2) 之间以及 select(2) 和 pselect(2) 之间的关系:zmq_ppoll() 允许应用程序安全地等待,直到文件描述符就绪或直到捕获到信号。
当使用 'sigmask' 设置为 NULL 的 zmq_ppoll() 时,其行为与 zmq_poll() 完全相同。有关更多信息,请参见 zmq_poll。
要充分利用 zmq_ppoll(),必须构造并传递指向信号掩码的非 NULL 指针给 'sigmask'。有关更多详细信息,请参见 sigprocmask(2)。完成此操作后,在实际的 ppoll()(或 pselect(),参见下面的注意)系统调用内部,会执行一个由三个步骤组成的原子操作:1. 当前信号掩码被替换为 'sigmask' 指向的信号掩码。2. 执行实际的 poll() 调用。3. 恢复原始信号掩码。由于这些操作是原子执行的,因此在更改信号掩码的调用和 poll/select 系统调用之间没有竞态条件的发生机会。这意味着只有在此(原子)调用期间,我们可以解除阻塞某些信号,以便仅在此时处理它们,而不是在调用之外。这意味着实际上,我们将我们的轮询器扩展为一个函数,它不仅监视套接字的变化,还监视“POSIX 信号套接字”以获取传入的信号。在其他时间,这些信号将被阻塞,并且我们无需处理这些其他时间发生的系统调用中断。
注意
|
zmq_ppoll() 函数可能使用除了 ppoll() 之外的操作系统接口来实现或模拟,因此可能受到这些接口的限制,其方式可能未在此文档中定义。 |
注意
|
Windows 上没有 ppoll 或 pselect,因此 Windows 构建中不支持 zmq_ppoll()。它仍然可以调用,但其 'sigmask' 是 void 指针类型(因为 'sigset_t' 在 Windows 上也不可用),并且 zmq_ppoll() 将返回一个错误(参见下面的错误部分)。 |
线程安全
zmq_pollitem_t 数组只能由将要或正在调用 zmq_ppoll 的线程使用。
如果一个套接字包含在多个 zmq_pollitem_t 数组中,且每个数组由不同的线程拥有,则套接字本身需要是线程安全的(例如 Server, Client 等)。否则,行为是未定义的。
返回值
成功完成后,zmq_ppoll() 函数应返回 'revents' 中已通知事件的 zmq_pollitem_t 结构的数量,如果没有事件通知则返回 0
。失败时,zmq_ppoll() 应返回 -1
并将 'errno' 设置为下面定义的一个值。
错误
- ETERM
-
'items' 数组中至少一个成员引用了一个相关的 0MQ 'context' 已终止的 'socket'。
- EFAULT
-
提供的 'items' 无效 (NULL)。
- EINTR
-
在任何事件可用之前,操作被信号传递中断。
- EINTR
-
在任何事件可用之前,操作被信号传递中断。
- ENOTSUP
-
在此构建中未激活 zmq_ppoll()。
示例
参见 zmq_poll 的 示例部分。只需将 zmq_poll 调用替换为 zmq_ppoll,并为 'sigmask' 参数添加一个 NULL 参数即可。
// simple global signal handler for SIGTERM static bool sigterm_received = false; void handle_sigterm (int signum) { sigterm_received = true; } // set up signal mask and install handler for SIGTERM sigset_t sigmask, sigmask_without_sigterm; sigemptyset(&sigmask); sigaddset(&sigmask, SIGTERM); sigprocmask(SIG_BLOCK, &sigmask, &sigmask_without_sigterm); struct sigaction sa; memset(&sa, '\0', sizeof(sa)); sa.sa_handler = handle_sigterm; // poll zmq_pollitem_t items [1]; // Just one item, which refers to 0MQ socket 'socket' */ items[0].socket = socket; items[0].events = ZMQ_POLLIN; // Poll for events indefinitely, but also exit on SIGTERM int rc = zmq_poll (items, 2, -1, &sigmask_without_sigterm); if (rc < 0 && errno == EINTR && sigterm_received) { // do your SIGTERM business } else { // do your non-SIGTERM error handling }
另请参阅
您的操作系统关于 poll() 系统调用的文档。
作者
此页面由 0MQ 社区编写。要进行更改,请阅读 0MQ 贡献政策,网址为 https://zeromq.cn/how-to-contribute/。