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
function inc() {
global $g;
$g++;
}
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
move $g to register D
increment register D
move register D to $g
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é suivante
Dans le cadre de A
move $g to register D
// value of D is 0
// OS stores the content of registers and switches to thread B
// B increments $g to 1 and finishes working
// OS restores content of registers to the context of thread A
// Value of register D is now 0
increment register D
move register D to $g
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.