La risposta alla domanda è utilizzare l'astrazione Pool
e Worker
.
L'idea di base è che si ::submit
Threaded
oggetti al Pool
, che impila sul successivo disponibile Worker
, distribuire i vostri Threaded
oggetti (round robin) in tutti Workers
.
Segue è super semplice codice è per PHP7 (pthreads v3):
<?php
$jobs = [];
while (count($jobs) < 2000) {
$jobs[] = mt_rand(0, 1999);
}
$pool = new Pool(8);
foreach ($jobs as $job) {
$pool->submit(new class($job) extends Threaded {
public function __construct(int $job) {
$this->job = $job;
}
public function run() {
var_dump($this->job);
}
});
}
$pool->shutdown();
?>
I posti di lavoro sono inutili, ovviamente. Nel mondo reale, suppongo che il tuo array $jobs
continui a crescere, quindi puoi semplicemente scambiare lo per alcuni do {} while
e continuare a chiamare ::submit
per nuovi lavori.
Nel mondo reale, si desidera raccogliere i rifiuti nello stesso ciclo (basta chiamare Pool::collect
senza parametri per il comportamento predefinito).
Degno di nota, niente di tutto questo sarebbe possibile se fosse davvero il caso che PHP non era destinato a lavorare in ambienti multi-threaded ... è sicuramente è.
Questo è la risposta alla domanda, ma non lo rende il migliore soluzione al vostro problema.
Nei commenti si è ipotizzato che 8 thread che eseguono il codice Symfony occupino meno memoria di 8 processi. Questo non è il caso, PHP non è condiviso nulla, tutto il tempo. Ci si può aspettare che 8 thread di Symfony occupino tutta la memoria di 8 processi di Symfony, anzi, un po 'di più. Il vantaggio dell'utilizzo di thread sui processi è che possono comunicare, sincronizzarsi e (sembrare) condividere l'uno con l'altro.
Solo perché è possibile, non significa che dovresti. La soluzione migliore per l'attività in corso è probabilmente quella di utilizzare un pacchetto già pronto o un software destinato a fare ciò che è necessario.
Studiare questa roba così bene da implementare una soluzione robusta è qualcosa che richiederà molto tempo e non vorreste implementare quella prima soluzione ...
Se si decide di ignorare il mio consiglio e provarlo, è possibile trovare molti examples nel repository github per pthreads.
php non è veramente progettato per il multi-threading, i documenti pthreads hanno avvertimenti importanti su di esso. L'opzione più semplice sarebbe quella di trasferire tutte le attività in una coda, quindi avviare il numero x di processi (exec) per soddisfare la coda. Un'altra opzione sarebbe quella di dividere le attività in gruppi di (taskcount/x), e di nuovo avviare x processi, passando un gruppo ad ogni processo – Steve
non è sicuro che avere un thread per una data quantità di oggetti sia una buona scelta, si avrà molto di thread se hai molti oggetti e il tuo programma diventerà più lento invece di diventare più veloce. IMHO è per questo che i thread sono corretti negli esempi che hai trovato – Freelancer
Posso suggerirti questo? https://github.com/facile-it/paraunit Sono il mantainer, ho usato Symonfy Process; non è il tuo caso d'uso ma forse può darti un vantaggio ... O potresti dare un'occhiata a https://github.com/liuggio/fastest – Jean