Heim >Backend-Entwicklung >PHP-Tutorial >Detaillierte Erläuterung des PHP-Coroutine-Inhalts

Detaillierte Erläuterung des PHP-Coroutine-Inhalts

不言
不言Original
2018-07-31 09:25:191730Durchsuche

Dieser Artikel teilt Ihnen den Inhalt von PHP Xiecheng mit. Ich hoffe, er kann Freunden in Not helfen.

Konzept

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:

  1. Zusammenarbeit. Da es sich um eine vom Programmierer selbst geschriebene Planungsstrategie handelt, erfolgt die Umschaltung eher durch Zusammenarbeit als durch Vorkaufsrecht

  2. 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.

Iterator

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,迭代结束

Generator

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

Eine ausführliche Erläuterung der einzelnen Methoden des Generators finden Sie im Dokument: http://php.net /manual/zh/class.generator.php

Hinweis:

Der Generator kann nicht direkt wie eine Funktion aufgerufen werden:

1. für jeden

2. senden ($value)

3. aktuell / nächstes...

Die Syntax von yield ist sehr flexibel. Wir verwenden das folgende Beispiel, damit jeder die Verwendung der yield-Syntax verstehen kann.

Anwendungsfall 1: Ausbeute an CPU-Ausführungsrechten

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.
Anwendungsfall 2: Rückgabe von Ausbeute

// 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);

Ausgabe:

This is task 2 iteration 1.
string(3) "lm1"
This is task 2 iteration 2.
string(3) "lm2"

Anwendungsfall 3: Ertrag erhält Wert

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变量

Ausgabe:

This is task 3 iteration 1.
aa This is task 3 iteration 2.

Anwendungsfall 4: Ertrag, Empfang und Rückgabe werden zusammen geschrieben

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

Ausgabe:

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"

Verwandte Empfehlungen:

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn