无法在C中的PHP_FUNCTION()内调用另一个函数

时间:2016-01-14 19:10:48

标签: php c multithreading php-internals

我需要调用C中PHP_FUNCTION()函数内的函数来扩展PHP,这是一个多线程脚本,函数本身使用int main()完美运行。这是我试图实现的目标。

#define NUM_THREADS 3
char *messages[NUM_THREADS];

void *PrintHello(void *threadid)
{
    zend_printf("gP");
    int *id_ptr, taskid;
    sleep(4);
    id_ptr = (int *) threadid;
    taskid = *id_ptr;
    zend_printf("Thread %d: %s\n", taskid, messages[taskid]);
    pthread_exit(NULL);
}


PHP_FUNCTION(hello_world)
{
    pthread_t threads[NUM_THREADS];
    int *taskids[NUM_THREADS];
    int rc, t;
    messages[0] = "English: Hello World!";
    messages[1] = "French: Bonjour, le monde!";
    messages[2] = "Spanish: Hola al mundo";

    for(t=0; t < NUM_THREADS; t++)
    {
        taskids[t] = (int *) malloc(sizeof(int));
        *taskids[t] = t;

        zend_printf("Creating thread %d\n <br>", t);
        rc = pthread_create(&threads[t], NULL, (void* (*) (void*)) pthreads_routine, (void *) taskids[t]);


        if (rc) {
            zend_printf("ERR; pthread_create() ret = %d\n", rc);
        }
    }
}

我需要从中调用PrintHello()函数 rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]);

我是否还需要在

中注册 void *PrintHello(void *threadid)
const zend_function_entry my_functions[] = {
    PHP_FE(hello_world, NULL)
    PHP_FE_END
};

var_dump()输出

Creating thread 0 
Creating thread 1 
Creating thread 2 
NULL

void *PrintHello(void *threadid)函数的顶部我已经包含zend_printf("gP");行以确保调用该函数,并且从out out的外观来看很明显该函数未被调用。

我的环境是Mac OSX,xCode 7.2,PHP 7.0.1
我做错了什么?

1 个答案:

答案 0 :(得分:1)

您的代码中似乎有两个问题,这两个问题都解释了为什么您没有获得任何输出。

1)至少在我的测试中,似乎是zend_printf - &gt; php_printf - &gt; vspprintf不是线程安全的。一旦其中一个线程尝试调用zend_printf(),您的代码始终就会崩溃。但是,即使情况并非如此,还有:

2)假设你的php代码如下:

<?php
hello_world();

发生的事情是,当你调用pthread_create()时,它会立即返回创建线程,尽管线程不一定开始运行。然后,一旦创建了所有线程,hello_world就会返回。然后,你的主线程结束,因为没有别的事可做。

主线程结束后,您生成的线程会立即终止。如果您根本没有看到任何内容,那是因为主线程在实际安排任何pthread之前结束,甚至在它们执行zend_printf("gP");行之前就已结束。

如果您将PHP代码更改为:

<?php
hello_world();
sleep(10);

然后你给孩子线程足够的时间来安排和给予CPU时间(此时他们可能会崩溃调用第一个zend_printf),如果没有,给他们足够的时间让它超过{ {1}}转到sleep(4)

如果您将zend_printf(Thread id)替换为:

PrintHello

(将void *PrintHello(void *threadid) { int *id_ptr, taskid; id_ptr = (int *) threadid; taskid = *id_ptr; printf("Thread %d: start\n", taskid, messages[taskid]); sleep(4); printf("Thread %d: %s\n", taskid, messages[taskid]); pthread_exit(NULL); } 替换为常规zend_printf),然后您将获得所需的输出,至少在cli上。