Невозможно вызвать другую функцию в PHP_FUNCTION () в C

1

Мне нужно вызвать функцию внутри функции 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
Что я делаю не так?

  • 0
    Какую именно ошибку или неправильное поведение вы видите?
  • 0
    Я включил информацию в вопрос. Благодарю вас!
Показать ещё 2 комментария
Теги:
multithreading
php-internals

1 ответ

1
Лучший ответ

Кажется, у вас есть две проблемы в коде, оба из которых объясняют, почему вы не получаете какой-либо результат.

1) По крайней мере, в моих тестах оказалось, что zend_printfphp_printfvspprintf не является потокобезопасным. Ваш код всегда сбой для меня, как только один из потоков пытается вызвать 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), тогда вы получите желаемый результат, по крайней мере, на кли.

  • 0
    Круто, большое спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню