我正在尝试编写和运行一个PHP扩展,该扩展派生出一个pthread(使用C中的POSIX库(,它可以分离并永远运行(它从队列中读取消息,但就这个问题而言,这并不重要,我只是想让它派生出一种只分离并返回以验证概念的函数(。
澄清一下:这不是在php中使用pthreads扩展,而是在自定义php扩展中使用POSIX pthreads库。我已经确认该环境可以编译和执行使用POSIXpthreads库的C代码。
线程的旋转函数是:
static int init_thread()
{
int ret = 0;
pthread_t thread;
ret = pthread_create(&thread, NULL, threadFunc, NULL);
if (ret != 0)
{
fprintf(stderr, "pthread_create failed with error code %dn", ret);
return -1;
}
return 0;
}
但这似乎阻止了任何扩展的执行。
Note
:我还尝试使用php扩展全局变量pthread_t,而不是在init_thread
中实例化pthread_t,但结果相同。。。
这个函数在RINIT中被调用,并且只在PHP工作进程第一次启动时被调用,而不是每次请求(我已经单独确认了这一点(。为了调试,我用threadFunc
测试了所有这些,只是简单地分离并用pthread_detach(pthread_self());
和return 0;
返回。
通过从MINIT、GINIT甚至RINIT打印到日志文件,我已经确认扩展设置正确,并且在没有pthread_create
行的情况下可以工作。
然而,每当init_thread
中的ret = pthread_create(&thread, NULL, threadFunc, NULL);
行被取消注释时,扩展中似乎什么都没有运行。
例如,MINIT应该在RINIT运行之前运行,我创建并写入一个文件以确认MINIT正在运行(我用这个文件作为扩展插件正在按预期执行代码的"证据"(。然而,当pthread_create
行被取消注释时,MINIT创建的文件甚至永远不会被生成或写入,即使MINIT应该在到达pthread_create
之前运行。
nginx或php7.4日志文件中没有明显的错误,即使扩展插件似乎已损坏,站点也能正常工作。
我真的很难理解为什么这不起作用,因为我使用pthread_create只是为了派生一个分离和返回的函数。甚至不需要使用ZTS
进行构建,因为线程根本不与PHP交互(以防万一,我也尝试过定义ZTS
和COMPILE_DL_EXTNAME
来运行ZEND_TSRMLS_CACHE_DEFINE
,但没有成功(。
我使用php7.4运行所有这些,并使用phpize
、./configure
和make
将扩展名构建为.so文件,然后适当放置.so文件并在/etc/php/7.4/fpm/php.ini
中添加extension=EXTENSION_NAME
。
我们非常感谢所有的想法!
如果你所要做的只是启动一个比其父进程寿命更长的子进程,那么有更简单的方法,例如从你的PHP主线程调用这样的东西:
shell_exec('bash -c "php myotherthread.php" 2>1 >/dev/null &');