从另一个线程将事件发送到nginx事件循环



我有第三方库,它是非阻塞的,有自己的事件循环,它接受回调函数的指针,并在同一线程中执行它。我想要的是张贴事件从这个线程到nginx主线程,像ngx_add_timer但没有时间选项,以安全地添加事件到nginx主事件循环。

所以很晚才在这里聚会,但我在我的研究中发现了这个线程,并想张贴我想到的解决方案

Nginx有一个机制,从一个工作线程——一个可能正在运行另一个事件循环——到Nginx工作进程的主线程。这是'ngx_post_event',它允许你发布一个事件处理程序,它将在未来的某个时候被主线程调用。

您必须选择一个事件队列来发布它,但无论您在做什么,答案肯定是&ngx_posted_events。

这里我们遇到了问题(和解决方案):如果你这样做,你的事件处理程序将不会被及时调用,因为主nginx工作进程线程正在等待i/o。它甚至不会屈尊查看发布的事件队列,直到它有一些"真正"的工作要从i/o做。

目前对我来说有效的解决方案(请记住这仅适用于Linux)是向主线程发送一个信号,该信号将从其epoll_wait幻想中唤醒,以便它可以开始处理来自另一个线程的管道。

是这样的:

首先获取工作进程主线程的id,并将其保持在进程全局状态:

//In you 'c'来源:

//在nginx启动时运行的一些代码中(在我的情况下是模块的预配置步骤)

nginx_thread = pthread_self();

现在,当你发布你的回调时,你使用我之前提到的ngx_post_event调用,然后发送一个SIGIO信号到主线程唤醒epoll_wait操作

// Post the event and wake up the Nginx epoll event loop
ngx_post_event( event_ptr, &ngx_posted_events );
pthread_kill( nginx_thread, SIGIO );

SIGIO事件在主Nginx信号处理程序中处理-并且被忽略(这就是日志所说的),但至关重要的是,导致发布的事件立即被处理。

就是这样——到目前为止,它似乎是有效的……请指出我做过的任何蠢事。

要完成这个故事,你需要以下#包括:

# include & lt; pthread.h>

# include & lt; signal.h>

最新更新