이 기사는 특정 참고 가치가 있는 PHP Synergy에 대한 내용을 공유합니다. 도움이 필요한 친구들에게 도움이 되기를 바랍니다.
우리는 다중 프로세스와 다중 스레드가 동시성을 달성하는 효과적인 방법이라는 것을 알고 있습니다. 그러나 멀티 프로세스의 컨텍스트 전환 리소스 오버헤드는 너무 높습니다. 멀티 스레딩의 오버헤드는 훨씬 작습니다. 이는 현재 주류 방식이지만 제어가 커널에 있으므로 사용자(프로그래머)가 제어할 수 없습니다. 코드 및 스레드 컨텍스트 전환에도 특정 오버헤드가 있습니다. 이때, 위와 같은 문제를 해결하기 위해 '코루틴'이라는 개념이 등장하게 되었다. 코루틴을 더 가벼운 스레드로 생각할 수 있습니다. 이런 종류의 스레드를 "사용자 공간 스레드"라고 합니다. 코루틴에는 다음과 같은 두 가지 특성이 있습니다.
협업. 프로그래머가 직접 작성한 스케줄링 전략이므로 선점이 아닌 협업을 통해 전환합니다
생성, 전환, 소멸은 사용자 모드에서 완료됩니다
PHP의 코루틴 지원은 반복 생성기에 있습니다. 의 에는 데이터를 생성기로 다시 보내는 기능(호출자가 호출된 생성기 함수에 데이터를 보냅니다)이 추가됩니다. 이는 생성자에서 호출자까지의 단방향 통신을 둘 사이의 양방향 통신으로 전환합니다.
여기에서는 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,迭代结束
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
참고:
Generator 호출 방법은 다음과 같습니다.
1.send($value)
3.
yield
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"
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"
PHP에서 추상 클래스 및 인터페이스를 사용하는 방법(코드)
위 내용은 PHP 코루틴 내용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!