无法在 C 中的 PHP_FUNCTION() 中调用另一个函数
Cannot invoke another function within a PHP_FUNCTION() in C
我需要在 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, <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()
时,它 returns 立即创建了线程,尽管线程不一定已开始 运行。然后,hello_world
returns 一旦创建了所有线程。然后,您的主线程结束,因为没有其他事情可做。
主线程结束后,您生成的线程也会立即终止。如果您什么也没看到,那是因为主线程在实际调度任何 pthread 之前结束,甚至在它们执行您的 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 上是这样。
我需要在 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, <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()
时,它 returns 立即创建了线程,尽管线程不一定已开始 运行。然后,hello_world
returns 一旦创建了所有线程。然后,您的主线程结束,因为没有其他事情可做。
主线程结束后,您生成的线程也会立即终止。如果您什么也没看到,那是因为主线程在实际调度任何 pthread 之前结束,甚至在它们执行您的 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 上是这样。