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

标签 php c multithreading php-internals

我需要在 PHP_FUNCTION() 中调用一个函数C 中的函数以扩展 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, <strong>PrintHello</strong>, (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");行以确保函数被调用,从输出的外观来看,很明显该函数没有被调用。

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

最佳答案

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

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

2) 假设您的 php 代码如下所示:

<?php
hello_world();

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

一旦主线程结束,您生成的线程将立即终止。如果您什么也没看到,那是因为主线程在任何 pthreads 实际调度之前结束,甚至在它们执行您的 zend_printf("gP"); 行之前。

如果您将 php 代码更改为:

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

然后你给子线程足够的时间来调度和给定 CPU 时间(此时他们可能会崩溃调用第一个 zend_printf),如果没有,给他们足够的时间来完成它通过 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 替换为常规 printf),然后您将获得所需的输出,至少在 cli 上是这样。

关于php - 无法在 C 中的 PHP_FUNCTION() 中调用另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34797764/

相关文章:

c++ opencv图像不显示在boost线程内

php - 我的 session 在重定向时总是丢失数据

c - 在二进制文件的最开始放置一个函数

java.lang.IllegalThreadStateException : Thread already started error when using selectors with SocketChannel

python - numpy 和 ctypes : dealing with views

c - 在函数内部修改字符串地址

c++ - 并行线程中的数据库访问,可行的选择?

php - 更改 PHPSESSID cookie 的名称会得到什么?

javascript - AngularJS withCredentials 不发送

javascript - 更改图像时闪烁