PHP扩展:来自pthread的call_user_function返回错误

时间:2013-05-19 10:15:39

标签: php pthreads php-extension

我目前正在开发PHP扩展。这个PHP扩展也应该通过pthreads使用多线程。在线程内部,应通过call_user_function调用PHP用户空间中的函数。 PHP配置了--enable-maintainer-zts配置选项。

我已经编写了一些在用户空间中调用PHP函数的代码,它按预期工作。请参阅以下代码片段以获取最小的工作示例:

扩展代码(在C中)

PHP_FUNCTION(hello_world)
{
    startWorker();
    RETURN_NULL();
}

void *startWorker() {

    static zval retval;

    zval function_name;
    INIT_ZVAL(function_name);
    ZVAL_STRING(&function_name, "hello", 1);

    TSRMLS_FETCH();

    if (call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC) == SUCCESS) {
        printf("successfully called function\n");
    } else {
        printf("calling user function returned an error\n");
    }

    zval_dtor(&function_name);
}

PHP代码:

<?php

function hello() {
        echo "php hello() called\n";
}
hello_world();

如果我调用PHP代码,它将返回以下输出 - 正如预期的那样。

php hello() called
successfully called function

但是现在我想从一个新线程调用PHP函数。所以我修改扩展代码如下:

PHP_FUNCTION(hello_world)
{
    pthread_t thread;
    pthread_create( &thread, NULL, &startWorker, NULL);
    pthread_join(thread, NULL);
    RETURN_NULL();
}

但是现在,突然之间,调用PHP代码导致以下输出:

calling user function returned an error

我可以通过zend_call_function中的if语句跟踪错误的来源,但是我不知道为什么EG(active)在这一点上是假的,我怎么能阻止这个:

if (!EG(active)) {
    return FAILURE; /* executor is already inactive */
}

所以我的问题是:

  • 甚至可以在线程中调用PHP用户空间函数吗?
  • 如果是,为什么call_user_function会返回错误?
  • EG(有效)是什么意思?如何在pthread中将其评估为true?

对此有任何提示都非常感谢。

0 个答案:

没有答案