J'utilise pthreads pour créer plusieurs threads. Chacun de ces threads à un moment donné essaie d'utiliser get_posts()
comme suit:
$args = array(
'post_type' => 'post',
'post_status' => 'any'
);
$posts_list = get_posts($args);
Cependant, je me retrouve avec le crash suivant:
HP Fatal error: Call to a member function get() on a non-object in C:\dev\wordpress\wp-includes\cache.php on line 123
VEUILLEZ NOTER que lorsque je fais le même get_posts()
appel dans une section de code qui n'est pas filetée, je n'ai pas le plantage.
Maintenant, ma question, comment appeler à get_posts()
partir d'un thread pthread ? Et si je ne peux pas faire ça, quelle est l'alternative?
Merci.
Mise à jour
Voici un exemple de code
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()
appel dans une section de code qui n'est pas enfilée, je n'ai pas le plantage "; donc ce n'est pas un problème avec monget_posts($args)
appel. De plus, il n'y a pas de code qui doit être protégé à ce stade, je lis simplement à partir de la base de données WordPress viaget_posts($args)
.Réponses:
Puisqu'il y a tellement de votes positifs à la question, bien que les problèmes de multithreading soient tout simplement trop larges pour un format de réponse, j'essaierai d'expliquer pourquoi vous ne devriez pas utiliser l'API wordpress de manière multithread ....
TL; DR - PHP n'est pas supposé être prêt pour le multithreading, le problème n'est pas PHP lui-même mais principalement les bibliothèques qu'il utilise. C'est pourquoi il est recommandé de ne pas utiliser le mode d'exécution multithread dans apache bien qu'en théorie il devrait être un peu plus rapide. Pour ajouter au problème de la couche sous-jacente qui n'est pas prête pour le multithread, wordpress core viole l'exigence la plus basique du multithread - pas d'accès gratuit aux globaux.
Quel est le problème avec les globaux dans un environnement multithread? supposons que nous avons le code naïf
Bien qu'il ne s'agisse que d'une seule ligne, ce n'est pas une opération atomique pour le CPU, et il faut plusieurs instructions au niveau de la machine pour l'exécuter. Quelque chose comme
Supposons maintenant que nous avons deux threads AB qui appellent
inc()
en "même temps" (évidemment avec un seul processeur, il n'y a pas de même temps), et que la valeur initiale de $ g est 0, quelle serait la valeur de $ g une fois les deux fils terminés? Cela dépendra de la façon dont le système d'exploitation gère le multithreading, quand basculera-t-il entre les threads. Dans les systèmes d'exploitation de style "plus ancien", le thread devait déclarer en appelant une API que le contrôle pouvait en être retiré, mais cela entraînait de nombreux problèmes avec des processus de mauvais comportement bloquant le système à cet effet dans le système d'exploitation "moderne" que le système d'exploitation prend. contrôler quand il en a envie. Dans la vraie vie, le résultat du code sera que $ g aura une valeur de 2, mais il y a aussi la possibilité suivanteDans le cadre de A
Le résultat final est que $ g a la valeur 1.
De toute évidence, les globaux ne sont pas le seul problème et la gestion des entrées et des sorties est également au cœur des problèmes de mutithreading.
Dans le code multithreading approprié, vous utilisez lock / mutex / semaphore / pipe / socket .... pour sérialiser l'accès à ces ressources globales pour vous assurer qu'il y aura un résultat prévisible à l'opération. Wordpress ne fait pas ça.
Enfer, wordpress n'est même pas sûr pour plusieurs processus. La plupart du temps, il s'en tire car le schéma de base de données est construit d'une manière qui, dans la vie réelle, évite d'avoir à modifier les mêmes données de différents processus (différentes publications ont des lignes différentes et ne partagent pas de données), mais regardez le code de la barre latérale / widgets et essayez d'imaginer ce qui se passera si deux administrateurs tentent d'ajouter un widget différent exactement en même temps. Comme cela nécessitera la manipulation d'une option spécifique, le résultat final peut être soit les deux widgets ajoutés, soit un seul d'entre eux.
Retour au multithrading. Sous Unix, contrairement à Windows, le coût supplémentaire de la génération d'un processus au lieu d'un thread est négligeable, donc utiliser
wp_remote_get
avec une URL spéciale pour invoquer un "thread" supplémentaire est une chose très légitime à faire et évite presque tous les pièges associés au multithreading.la source