PHP 코루틴 내용에 대한 자세한 설명

不言
풀어 주다: 2023-04-03 13:46:01
원래의
1633명이 탐색했습니다.

이 기사는 특정 참고 가치가 있는 PHP Synergy에 대한 내용을 공유합니다. 도움이 필요한 친구들에게 도움이 되기를 바랍니다.

개념

우리는 다중 프로세스와 다중 스레드가 동시성을 달성하는 효과적인 방법이라는 것을 알고 있습니다. 그러나 멀티 프로세스의 컨텍스트 전환 리소스 오버헤드는 너무 높습니다. 멀티 스레딩의 오버헤드는 훨씬 작습니다. 이는 현재 주류 방식이지만 제어가 커널에 있으므로 사용자(프로그래머)가 제어할 수 없습니다. 코드 및 스레드 컨텍스트 전환에도 특정 오버헤드가 있습니다. 이때, 위와 같은 문제를 해결하기 위해 '코루틴'이라는 개념이 등장하게 되었다. 코루틴을 더 가벼운 스레드로 생각할 수 있습니다. 이런 종류의 스레드를 "사용자 공간 스레드"라고 합니다. 코루틴에는 다음과 같은 두 가지 특성이 있습니다.

  1. 협업. 프로그래머가 직접 작성한 스케줄링 전략이므로 선점이 아닌 협업을 통해 전환합니다

  2. 생성, 전환, 소멸은 사용자 모드에서 완료됩니다

PHP의 코루틴 지원은 반복 생성기에 있습니다. 의 에는 데이터를 생성기로 다시 보내는 기능(호출자가 호출된 생성기 함수에 데이터를 보냅니다)이 추가됩니다. 이는 생성자에서 호출자까지의 단방향 통신을 둘 사이의 양방향 통신으로 전환합니다.

Iterator

여기에서는 Iterator의 개념을 자세히 설명하지 않습니다. 우리가 직접 구현한 반복자를 살펴보겠습니다.

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);
}
로그인 후 복사

출력:

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

yeild가 포함된 메서드는 생성기입니다(생성기는 Iterator 인터페이스를 구현합니다. 즉, 생성기는 반복기의 특성을 가집니다). 생성기의 구현은 다음과 같습니다.

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
로그인 후 복사

출력:

1
2
3
4
5
6
7
8
9
10
1
2
로그인 후 복사

생성기의 각 방법에 대한 자세한 설명은 http://php.net/manual/zh/class.generator.php 문서를 참조하세요.

참고:

Generator 호출 방법은 다음과 같습니다.

1.send($value)

3.

yield

yield의 구문은 매우 유연합니다. 다음 예를 사용하여 모든 사람이 항복 구문의 사용을 이해할 수 있도록 합니다.

사용 사례 1: CPU 실행 권한 포기

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
로그인 후 복사

출력:

This is task 1 iteration 1.
This is task 1 iteration 2.
로그인 후 복사

사용 사례 2: Yield return

// 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"
로그인 후 복사

사용 사례 3: Yield가 값을 받습니다

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.
로그인 후 복사

사용 사례 4: Yeild 수신 및 반환이 함께 작성됩니다.

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"
로그인 후 복사
관련 권장 사항:

PHP에서 추상 클래스 및 인터페이스를 사용하는 방법(코드)

PHP 페이징 및 정기 확인 코드 구현

위 내용은 PHP 코루틴 내용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!