Мне нужно вызвать функцию внутри функции 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, 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");
чтобы убедиться, что функция вызывается, а из внешнего вида очевидно, что функция не вызывается.
Моя среда - 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);
Затем вы даете дочерним потокам достаточное время для планирования и даете процессорное время (в этот момент они, вероятно, сбой zend_printf
первый 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
), тогда вы получите желаемый результат, по крайней мере, на кли.