Вызов функций php с использованием pthread в C

Мне нужно многопоточность функции PHP, но когда я вызываю функцию PHP, я получаю эту ошибку «Safari не могу открыть страницу»Safari can’t open the page “‎localhost/home.php” because the server unexpectedly dropped the connection. This sometimes occurs when the server is busy. Wait for a few minutes, and then try again.

У меня есть эти строки в моем PHP-файле

<?php
echo "Hello World","<br>";
open_thread("hello");

function hello() {
echo "Hello World";
}

Когда я удаляю hello от open_thread("hello");просто выводит это предупреждение:
Warning: open_thread() expects exactly 1 parameter, 0 given in /Users/username/Sites/home.php on line 3

Это также происходит, когда я вызываю функцию C, в которой есть выходные данные, когда я удаляю выходные данные из функции, сервер работает и ничего не отображает.

Проблема возникает здесь pthread_join(tid, NULL);

Вот мои C коды

PHP_FUNCTION(open_thread)
{

zval *threaded_func;
zend_string *func_name;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &threaded_func) != SUCCESS) {
return;
}if (Z_TYPE_P(threaded_func) != IS_NULL)
{
if (!zend_is_callable(threaded_func, 0, &func_name TSRMLS_CC))
{
php_error_docref(NULL TSRMLS_CC, E_WARNING, "’%s’ is not a valid read callback", func_name);
efree(func_name);
RETURN_FALSE;
}
efree(func_name);
}pthread_t tid;
zend_printf("Starting..\n");
pthread_create(&tid, NULL, (void *) threaded_func, NULL);
pthread_join(tid, NULL);
zend_printf("Finished\n");
}

Вопрос
Это потокобезопасная проблема? как мне это исправить?

1

Решение

PHP может быть создан для поддержки многопоточного SAPI — режима ZTS — однако важно понимать, что используемая модель памяти ничего не делит.

В модели без общего доступа у каждого потока есть свой интерпретатор (компилятор, исполнитель, все глобальные переменные модуля, весь пользовательский код, вся партия).

Это означает разные вещи:

  • Код, скомпилированный для потока A, не может быть выполнен потоком B. Поток B должен скопировать код из потока A, выполнить что-то вроде pass_two и выполнить копию кода.
  • Код, скопированный из потока A, который ссылается на объекты, ресурсы или хеш-таблицы, может (будет) сломаться без надлежащей подготовки и / или соответствующих обработчиков объектов.

Простой запуск потока и попытка вызвать Zend обречены на неудачу, так как он игнорирует природу PHP, не имеющую общего доступа.

Поток новых потоков должен быть примерно таким:

void routine(void *thing) {
ts_resource(0);

php_request_startup();

/* do stuff */

php_request_shutdown();

ts_free_thread();
}
  • ts_resource: это инициализирует TSRM в новом потоке, в свою очередь инициализируя некоторые из Zend
  • php_request_startup: инициализирует все остальное, кроме всего прочего работает RINIT для всех модулей
  • php_request_shutdown: это работает RSHUTDOWNв общем, убирает
  • ts_free_thread: необязательно, в противном случае может произойти при остановке процесса (когда TSRM окончательно завершается)

Как таковой, пример потока также потерпит неудачу, если попытается вызвать код пользователя, скомпилированный (для) другого потока: после запуска запроса и до того, как вы сможете вызвать код пользователя, вам нужно сначала скопировать код в текущий контекст.

Мелкие детали того, как все это работает в реальном мире, можно найти в источниках расширения pthreads.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]