Estoy usando pthreads para crear múltiples hilos. Cada uno de esos hilos en un punto intenta usar get_posts()
lo siguiente:
$args = array(
'post_type' => 'post',
'post_status' => 'any'
);
$posts_list = get_posts($args);
Sin embargo, termino con el siguiente bloqueo:
HP Fatal error: Call to a member function get() on a non-object in C:\dev\wordpress\wp-includes\cache.php on line 123
TENGA EN CUENTA que cuando hago la misma get_posts()
llamada en una sección de código que no está enhebrada, no tengo el bloqueo.
Ahora, mi pregunta, ¿cómo llamar get_posts()
desde un hilo pthread ? Y si no puedo hacer eso, ¿cuál es la alternativa?
Gracias.
Actualizar
Aquí hay un código de muestra
class My_Thread extends Thread {
public function run() {
/* DO SOME STUFF HERE */
$args = array(
'post_type' => 'post',
'post_status' => 'any'
);
$posts_list = get_posts($args); // <------ This is causing the crash
}
}
// Create a array
$threads = array();
//Iniciate Miltiple Thread
foreach ( range("A", "C") as $i ) {
$threads[] = new My_Thread($i);
}
// Start The Threads
foreach ($threads as $thread) {
$thread->start();
}
get_posts()
llamada en una sección de código que no está enhebrada, no tengo el bloqueo "; entonces no es un problema con miget_posts($args)
llamada. Además, no hay código que deba protegerse en este momento, solo estoy leyendo desde la base de datos de WordPressget_posts($args)
.Respuestas:
Dado que hay tantos votos a favor de la pregunta, aunque los problemas de subprocesamiento múltiple son demasiado amplios para un formato de respuesta, intentaré explicar por qué no debe usar la API de WordPress de forma multiproceso ...
TL; DR: no se supone que PHP esté preparado para subprocesos múltiples, el problema no es PHP en sí, sino principalmente las bibliotecas que utiliza. Es por eso que se recomienda no utilizar el modo de ejecución multiproceso en apache, aunque en teoría debería ser algo más rápido. Para agregar al problema de que la capa subyacente no está lista para múltiples subprocesos, el núcleo de WordPress viola el requisito más básico de múltiples subprocesos: no hay acceso libre a globales.
¿Cuál es el problema con los globales en un entorno multiproceso? supongamos que tenemos el código de aspecto ingenuo
Si bien es solo un trazador de líneas, no es una operación atómica para la CPU, y se requieren varias instrucciones de nivel de máquina para ejecutarlo realmente. Algo como
Ahora supongamos que tenemos dos hilos AB que llaman
inc()
al "mismo tiempo" (obviamente con una sola CPU no existe el mismo tiempo), y que el valor inicial de $ g es 0, ¿cuál sería el valor de $ g después de que ambos hilos terminaron? Dependerá de cómo maneje el sistema operativo los subprocesos múltiples, cuándo cambia entre hilos. En los sistemas operativos de estilo "anterior", era el trabajo del subproceso declarar llamando a una API que se le puede quitar el control, pero eso genera muchos problemas con procesos de comportamiento incorrecto que bloquean el sistema en el sistema operativo "moderno" que toma el sistema operativo control cuando quiera. En la vida real, el resultado del código será que $ g tendrá un valor de 2, pero también existe la siguiente posibilidadEn el contexto de A
El resultado final es que $ g tiene el valor de 1.
Obviamente, los globales no son el único problema y el manejo de entradas y salidas también es un núcleo para problemas de multiples hilos.
En un código de subprocesamiento adecuado, use lock / mutex / semaphore / pipe / socket ... para serializar el acceso a dichos recursos globales para asegurarse de que la operación tendrá un resultado predecible. Wordpress no hagas eso.
Demonios, WordPress ni siquiera es seguro para múltiples procesos. La mayoría de las veces se sale con la suya porque el esquema de DB está construido de una manera que, en el uso de la vida real, evita la necesidad de modificar los mismos datos de diferentes procesos (diferentes publicaciones tienen diferentes filas y no comparten datos), pero observe el código de la barra lateral / widgets e intente imaginar qué sucederá si dos administradores intentan agregar un widget diferente exactamente al mismo tiempo. Como esto requerirá la manipulación de una opción específica, el resultado final puede ser ambos widgets agregados o solo uno de ellos.
De vuelta a multitrading. En Unix, a diferencia de Windows, el costo adicional de generar un proceso en lugar de un subproceso es insignificante, por lo tanto, usar
wp_remote_get
una url especial para invocar un "subproceso" adicional es algo muy legítimo y evitar casi todos los obstáculos asociados con el subprocesamiento múltiple.fuente