Dieser Artikel teilt Ihnen den Inhalt von PHP Xiecheng mit. Ich hoffe, er kann Freunden in Not helfen.
Wir wissen, dass Multiprozess und Multithread effektive Möglichkeiten sind, um Parallelität zu erreichen. Allerdings ist der Overhead der Kontextwechsel-Ressourcen bei Multiprozessen viel geringer, was auch die aktuelle Mainstream-Praxis ist, aber seine Kontrolle liegt im Kernel, sodass der Benutzer (Programmierer) die Kontrolle darüber verliert Der Code und der Thread-Kontextwechsel haben ebenfalls einen gewissen Overhead. Zu diesem Zeitpunkt entstand das Konzept der „Coroutine“, um die oben genannten Probleme zu lösen. Sie können sich Coroutinen als leichtere Threads vorstellen. Diese Art von Thread wird als „User-Space-Thread“ bezeichnet. Coroutinen haben die folgenden zwei Eigenschaften:
Zusammenarbeit. Da es sich um eine vom Programmierer selbst geschriebene Planungsstrategie handelt, erfolgt die Umschaltung eher durch Zusammenarbeit als durch Vorkaufsrecht
Erstellung, Wechsel und Zerstörung werden im Benutzermodus abgeschlossen
PHPs Unterstützung für Coroutinen basiert auf dem iterativen Generator und fügt die Funktion hinzu, Daten zurück an den Generator zu senden (der Aufrufer sendet Daten an die aufgerufene Generatorfunktion). Dadurch wird die einseitige Kommunikation vom Generator zum Anrufer in eine zweiseitige Kommunikation zwischen beiden umgewandelt.
Das Konzept des Iterators wird hier nicht im Detail besprochen. Werfen wir einen Blick auf einen Iterator, den wir selbst implementiert haben.
class MyIterator implements Iterator { private $var = array(); public function __construct($array) { if (is_array($array)) { $this->var = $array; } } public function rewind() { // 第一次迭代时候会执行(或调用该方法的时候),后面的迭代将不会执行。 echo "rewinding\n"; reset($this->var); } public function current() { $var = current($this->var); echo "current: $var\n"; return $var; } public function key() { $var = key($this->var); echo "key: $var\n"; return $var; } public function next() { // 最后执行,就是执行完下面sleep(2)后再执行。(执行了next本次迭代才算结束) $var = next($this->var); echo "next: $var\n"; return $var; } public function valid() { // 当valid返回false的时候迭代结束 $var = $this->current() !== false; echo "valid: {$var}\n"; return $var; } } $values = array(1,2,3,4); $it = new MyIterator($values); foreach ($it as $a => $b) { // 进行迭代(每次迭代,会依次执行以下方法: rewind(特别之处见上面解释), valid, current, key, next) print "=====\n"; sleep(2); }
Ausgabe:
rewinding current: 1 // 因为valid里面调用了current, 这里current出来一次 valid: 1 current: 1 key: 0 ===== next: 2 current: 2 valid: 1 current: 2 key: 1 ===== next: 3 current: 3 valid: 1 current: 3 key: 2 ===== next: 4 current: 4 valid: 1 current: 4 key: 3 ===== next: current: valid: // valid返回false,迭代结束
Die Methode von yeild ist ein Generator (der Generator implementiert die Iterator-Schnittstelle, d. h. ein Generator hat die Eigenschaften eines Iterators). Die Implementierung des Generators ist wie folgt:
function xrange($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { echo $i . "\n"; yield; } } // foreach方式 foreach (xrange(1, 10) as $num) { } $gene = xrange(1, 10); // gene就是一个生成器对象 // current $gene->current(); // 打印1 // next $gene->next(); $gene->current() // 打印2
Ausgabe:
1 2 3 4 5 6 7 8 9 10 1 2
Hinweis:
Der Generator kann nicht direkt wie eine Funktion aufgerufen werden:
1. für jeden
2. senden ($value)
3. aktuell / nächstes...
function task1 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 1 iteration $i.\n"; yield;// 遇到yield就会主动让出CPU的执行权; } } $a = task1(); $a->current(); // 执行第一次迭代 $a->send(1); // 唤醒当时让出CPU执行权的yield
Ausgabe:
This is task 1 iteration 1. This is task 1 iteration 2.
// yield返回 function task2 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 2 iteration $i.\n"; yield "lm$i"; // 遇到yield就会主动让出CPU的执行权,for暂停执行, 然后返回"lm"。放在yield后面的值就是返回值 } } $a = task2(); $res = $a->current(); // 第一次迭代, 遇到yield返回 var_dump($res); $res = $a->send(1); // 唤醒yield, for继续执行,遇到yield返回。 var_dump($res);
This is task 2 iteration 1. string(3) "lm1" This is task 2 iteration 2. string(3) "lm2"
function task3 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 3 iteration $i.\n"; $getValue = yield;// 遇到yield就会主动让出CPU的执行权;send后,将send值赋值给getValue echo $getValue . " "; } } $a = task3(); $a->current(); $a->send("aa"); // 唤醒yield,并将"aa"值赋值给$getValue变量
This is task 3 iteration 1. aa This is task 3 iteration 2.
function task4 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 4 iteration $i.\n"; $ret = yield "lm$i"; // yield, 然后返回lm$i; 当send时,将send过来的值赋值给$ret; echo $ret; } } $a = task4(); var_dump($a->current()); // 返回lm1 var_dump($a->send("hhh ")); // 先唤醒yield, 将"hhh "赋值给$ret,再返回lm2 var_dump($a->send("www ")); // 先唤醒yield, 将"www "赋值给$ret,再返回lm3
This is task 4 iteration 1. string(3) "lm1"hhh This is task 4 iteration 2. string(3) "lm2"www This is task 4 iteration 3. string(3) "lm3"
So verwenden Sie abstrakte Klassen und Schnittstellen in PHP (Code)
Code-Implementierung von PHP-Paging und regelmäßige Überprüfung
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des PHP-Coroutine-Inhalts. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!