検索
ホームページバックエンド開発PHPチュートリアルphp のコルーチンの詳細な紹介 (コード)
php のコルーチンの詳細な紹介 (コード)Sep 13, 2018 pm 04:57 PM
phpコルーチン

この記事では、最初に、yield の使用法とジェネレーターのインターフェイスに焦点を当てて、ジェネレーターの概念を紹介します。コルーチン編では、コルーチンの原理やPHPコルーチンプログラミングで注意すべき事項について簡単に説明します。

PHP は 5.5 からジェネレーター (Generator) を導入し、これに基づいてコルーチン プログラミングを実現できます。この記事はジェネレーターのレビューから始まり、その後コルーチン プログラミングに移ります。

yield とジェネレータ

Generator

Generator は、イテレータ インターフェイスを実装するデータ型です。ジェネレーター インスタンスは new を通じて取得できません。また、ジェネレーター インスタンスを取得するための静的メソッドはありません。ジェネレーター インスタンスを取得する唯一の方法は、ジェネレーター関数 (yield キーワードを含む関数) を呼び出すことです。ジェネレーター関数を直接呼び出すとジェネレーター オブジェクトが返され、ジェネレーターの実行中に関数内のコードの実行が開始されます。

最初にコードに移動して、yield とジェネレーターを直感的に体験します。

# generator1.php
function foo() {
    exit('exit script when generator runs.');
    yield;
}

$gen = foo();
var_dump($gen);
$gen->current();

echo 'unreachable code!';

# 执行结果
object(Generator)#1 (0) {
}
exit script when generator runs.

foo関数には yield キーワードが含まれており、ジェネレーター関数に変換されます。 。 foo を呼び出すと、関数本体内のコードは実行されませんが、代わりにジェネレーター インスタンスが返されます。ジェネレーターの実行後、foo 関数内のコードが実行され、スクリプトが終了します。

名前が示すように、ジェネレーターを使用してデータを生成できます。データを生成する方法が他の関数と異なるだけです: ジェネレーターは return ではなく yield を介してデータを返します; yield がデータを返した後、ジェネレーター関数は破棄されます。操作を一時停止するだけで、将来一時停止から再開できます。ジェネレーターは 1 回実行すると 1 つのデータ (のみ) を返し、複数回実行すると複数のデータを返します。ジェネレーターはデータを取得するために呼び出されるのではなく、ジェネレーター内のコードはそこに存在します。いわゆる「毎回移動」とは、ジェネレーターがデータを生成する方法を指します。

ジェネレーターは反復子インターフェイスを実装しています。ジェネレーター データを取得するには、foreach ループまたは手動の current/next/valid を使用できます。次のコードは、データの生成と走査を示しています。

# generator2.php
function foo() {
  # 返回键值对数据
  yield "key1" => "value1";
  $count = 0;
  while ($count valid()) {
  fwrite(STDOUT, "key:{$gen->key()}, value:{$gen->current()}\n");
  $gen->next();
}

# foreach 遍历数据
fwrite(STDOUT, "\ndata from foreach\n");
foreach (foo() as $key => $value) {
    fwrite(STDOUT, "key:$key, value:$value\n");
}

yield

yieldキーワードはジェネレーターの核心であり、これにより通常の関数をジェネレーターに区別 (進化) させることができます。機能。 yield は「あきらめる」という意味です。プログラムが yield ステートメントまで実行すると、実行が一時停止され、CPU が放棄され、呼び出し元に制御が戻ります。次の実行は、次の実行から継続されます。中断ポイントを実装します。制御が呼び出し元に戻ると、yield ステートメントは呼び出し元に値を返すことができます。 generator2.phpこのスクリプトは、yield 戻り値の 3 つの形式を示しています。

  1. yield $key => $value: データのキーと値を返します。

  2. yield $value: データを返し、キーはシステムによって割り当てられます;

  3. yield: null 値を返し、キーはシステムによって割り当てられます。

yield関数をいつでも一時停止し、実行を継続し、呼び出し元にデータを返すことができます。実行を継続するために外部データが必要な場合、この作業はジェネレーターの send 関数によって提供されます。yield の左側に表示される変数は ## から変数を受け取ります。 #send 値。一般的な send 関数の使用例を見てみましょう:

function logger(string $filename) {
  $fd = fopen($filename, 'w+');
  while($msg = yield) {
    fwrite($fd, date('Y-m-d H:i:s') . ':' . $msg . PHP_EOL);
  }
  fclose($fd);
}

$logger = logger('log.txt');
$logger->send('program starts!');
// do some thing
$logger->send('program ends!');

send ジェネレーターと外部の間で双方向のデータ通信を行う機能: yieldデータを返す; send 操作を継続するためのサポート データを提供します。 send によりジェネレーターは実行を継続できるため、この動作はイテレータの next インターフェイスと似ています。ここで、nextsend(null と同等です) )

その他

  1. $string = yield $data; 式は PHP7 より前では無効であり、括弧が必要です: $string = (yield $data);

  2. ##PHP5 ジェネレーター関数は
  3. return

    値を返せません。PHP7 以降では値を返し、ジェネレーター getReturn を渡すことができます。戻り値を取得します。

  4. PHP7 は、ジェネレーターの委任を実装するために
  5. yield from

    構文を追加します。

  6. ジェネレーターは一方向の反復子であり、開始後に
  7. rewind

    を呼び出すことはできません。

  8. 概要

他のイテレータと比較して、ジェネレーターはパフォーマンスのオーバーヘッドが低く、コーディングが簡単であるという特徴があります。その役割は主に 3 つの側面に反映されます:

    データ生成 (プロデューサー)、イールドを通じてデータを返す;
  1. データ消費 (コンシューマー) 、送信からのデータを消費します;
  2. はコルーチンを実装します。
  3. ジェネレーターと PHP の基本的な使用法については、
2gua

のブログ投稿を読むことをお勧めします: PHP ジェネレーターは活発で、面白く、理解しやすいです。 コルーチン プログラミング

コルーチン (コルーチン) は、いつでも中断して再開できるサブルーチンです。

yield

キーワードを使用すると、関数にこの機能を持たせることができます。コルーチンプログラミングに使用できます。 プロセス、スレッド、コルーチン

スレッドはプロセスに属し、プロセスは複数のスレッドを持つことができます。プロセスはコンピュータにリソースを割り当てる最小単位であり、スレッドはコンピュータのスケジューリングと実行の最小単位です。プロセスとスレッドは両方ともオペレーティング システムによってスケジュールされます。

コルーチンは「ユーザー モード スレッド」とみなすことができ、ユーザー プログラムにスケジューリングを実装する必要があります。スレッドとプロセスは、「プリエンプティブ」方式で交互に実行されるようにオペレーティング システムによってスケジュールされ、コルーチンは積極的に CPU を放棄して「ネゴシエートされた」方式で交互に実行されます。コルーチンは非常に軽量で、コルーチンの切り替えにスレッド切り替えが不要で実行効率が高く、数が多いほどコルーチンの利点が反映されます。

ジェネレーターとコルーチン

ジェネレーターによって実装されるコルーチンはスタックレス コルーチンです。つまり、ジェネレーター関数には関数フレームのみがあり、実行時に呼び出し元のスタックにアタッチされます。強力なスタックフル コルーチンとは異なり、ジェネレーターは一時停止後のプログラムの方向を制御できず、制御を呼び出し元に受動的に返すことしかできません。ジェネレーターはコルーチン全体ではなく、それ自体に割り込むことしかできません。もちろん、ジェネレーターの利点は、効率が高く (一時停止時にプログラム カウンターを保存するだけで済みます)、実装が簡単であることです。

コルーチン プログラミング

PHP でのコルーチン プログラミングといえば、ブラザー ニアオが転載 (翻訳) したこのブログ投稿を読んだことがある人がほとんどだと思います: コルーチンを使用して PHP タスク スケジューリングで複数の機能を実現する。オリジナルの著者である nikic は、PHP の中心的な開発者であり、ジェネレーター関数の開始者および実装者です。ジェネレーターとそれに基づくコルーチン プログラミングについて詳しく知りたい場合は、ジェネレーターに関する nikic の RFC と Niaoge の Web サイトの記事が必読です。

まず、ジェネレーターに基づいたコルーチンの動作方法を見てみましょう。コルーチンは協調的に動作します。つまり、コルーチンは積極的に CPU を放棄して、複数のタスクを交互に実行します (つまり、同時マルチタスクですが、並列ではありません)。 ; ジェネレーターはコルーチンとみなすことができ、yield ステートメントが実行されると、CPU 制御は呼び出し元に戻り、呼び出し元は他のコルーチンまたは他のコードを実行し続けます。

バード兄弟のブログを理解することの難しさを見てみましょう。コルーチンは非常に軽量であり、数千のコルーチン (ジェネレーター) がシステム内に同時に存在できます。オペレーティング システムはコルーチンをスケジュールしません。コルーチンの実行を調整する作業は開発者にあります。ニアオ兄弟の記事には、コルーチン プログラミングがほとんどない (コルーチンを書くということは主にジェネレーター関数を書くことを意味します) と書かれているため、コルーチンの部分を理解していない人もいますが、彼らはコルーチン スケジューラー (スケジューラーまたはカーネル) の実装に多くの時間を費やしています。オペレーティング システムを管理し、すべてのコルーチンに対して公平なスケジューリングを実行します。 PHP 開発の一般的な考え方は次のとおりです。これらのコードを作成すると、PHP エンジンがコードを呼び出して期待される結果が得られます。コルーチン プログラミングでは、作業を実行するコードを記述するだけでなく、これらのコードにいつ動作するかを指示するコードを記述することも必要です。作者の考えをよく理解していないと当然理解は難しくなります。独自にスケジュールする必要があるため、ネイティブ コルーチン (async/await 形式) と比較したジェネレーター コルーチンの欠点となります。

コルーチンとは何なのか理解できたところで、何に使えるのでしょうか?コルーチンは連携してCPUを効率的に利用するために自らCPUを放棄しますが、当然放棄するタイミングはプログラムがブロックされたときです。プログラムはどこでブロックするのでしょうか?ユーザー モード コードがブロックされることはほとんどありません。ブロックは主にシステム コールによって発生します。システム コールの大部分は IO であるため、コルーチンの主なアプリケーション シナリオはネットワーク プログラミングです。プログラムのパフォーマンスと同時実行性を高めるには、プログラムはブロックせずに非同期で実行する必要があります。非同期実行には通知とコールバックが必要なため、コールバック関数を作成しても「コールバック地獄」の問題は避けられません。コードの可読性が低く、プログラムの実行プロセスがコールバック関数の層に分散されます。コールバック地獄を解決するには、主に Promise とコルーチンの 2 つの方法があります。コルーチンは同期方式でコードを作成できるため、高パフォーマンスのネットワーク プログラミング (IO 集中型) で推奨されます。

PHP でのコルーチン プログラミングを振り返ってみましょう。 PHP では、ジェネレーターに基づいてコルーチン プログラミングが実装されるため、RecoilPHPAmp などのコルーチン フレームワークを使用することをお勧めします。これらのフレームワークにはすでにスケジューラーが記述されており、その上でジェネレーター関数を直接開発すると、カーネルが自動的に実行をスケジュールします (関数をコルーチン モードで実行するようにスケジュールしたい場合は、単に yield を関数本体です)。コルーチン プログラミングに yield メソッドを使用したくない場合は、golang に似たコルーチン プログラミング エクスペリエンスを実現し、開発効率を高めることができる swoole またはその派生フレームワークをお勧めします。 PHPの。

オリジナルの PHP コルーチン プログラミングを使用したい場合は、Niao Ge のブログにあるものと同様のスケジューラが不可欠です。スケジューラはコルーチンの実行をスケジュールし、コルーチンが中断された後、制御はスケジューラに戻ります。したがって、スケジューラは常にメイン (イベント) ループ内にある必要があります。つまり、CPU がコルーチンを実行していないときは、スケジューラ コードを実行する必要があります。コルーチンなしで実行する場合、スケジューラは CPU の消費を避けるために自身をブロックし (Niao Ge のブログでは組み込みの select システム コールを使用しています)、イベントの到着を待ってから、対応するコルーチンを実行する必要があります。プログラムの実行中は、スケジューラーのブロックを除き、コルーチンは実行中にブロック API を呼び出すべきではありません。

概要

コルーチン プログラミングにおける yield の主な機能は、戻り値を気にせずに制御を渡すことです (基本的に yield戻り値次回の実行時に直接 send になります)。制御の転送のタイミングとコルーチンの動作に焦点を当てる必要があります。

さらに、コルーチンは非同期とはほとんど関係がなく、実行環境のサポートにも依存することを説明する必要があります。従来のPHP動作環境では、promise/coroutineを利用しても同期的にブロックされてしまいます。コルーチン フレームワークがどれほど優れていても、sleep はもはや使いやすいものではありません。たとえて言えば、JavaScript が Promise/Async テクノロジを使用していない場合でも、JavaScript は非同期であり、ノンブロッキングです。

ジェネレーターと Promise を使用すると、

await に似たコルーチン プログラミングを実装できます。関連するコードは Github に多数あるため、この記事では説明しません。

関連する推奨事項: PHP の

$_SERVER 詳細な紹介

PHP の Output_buffering の詳細な紹介、outputbuffering_PHP チュートリアル

以上がphp のコルーチンの詳細な紹介 (コード)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
如何在Swoole中使用协程实现高并发的swoole_smtp_auth函数如何在Swoole中使用协程实现高并发的swoole_smtp_auth函数Jun 25, 2023 am 08:28 AM

近年来,随着互联网应用的日益普及,各种高并发的场景也越来越常见。在这种情况下,传统的同步I/O方式已经无法满足现代应用对高性能、高并发的需求。因此,协程成为了一种被广泛应用的解决方案。Swoole是一款面向高并发、高性能的PHP网络通信框架,可以轻松实现异步、协程等特性。swoole_smtp_auth函数是其中一个常用的函数,它可以在使用SMTP协议进行邮

满满的干货!全面的介绍Python的协程是如何实现!看懂算你牛!满满的干货!全面的介绍Python的协程是如何实现!看懂算你牛!May 02, 2023 am 10:34 AM

如果你需要访问多个服务来完成一个请求的处理,比如实现文件上传功能时,首先访问Redis缓存,验证用户是否登录,再接收HTTP消息中的body并保存在磁盘上,最后把文件路径等信息写入MySQL数据库中,你会怎么做?首先可以使用阻塞API编写同步代码,直接一步步串行即可,但很明显这时一个线程只能同时处理一个请求。而我们知道线程数是有限制的,有限的线程数导致无法实现上万级别的并发连接,过多的线程切换也抢走了CPU的时间,从而降低了每秒能够处理的请求数量。于是为了达到高并发,你可能会选择一

如何在PHP中使用协程?如何在PHP中使用协程?May 12, 2023 am 08:10 AM

随着传统的多线程模型在高并发场景下的性能瓶颈,协程成为了PHP编程领域的热门话题。协程是一种轻量级的线程,能够在单线程中实现多任务的并发执行。在PHP的语言生态中,协程得到了广泛的应用,比如Swoole、Workerman等框架就提供了对协程的支持。那么,如何在PHP中使用协程呢?本文将介绍一些基本的使用方法以及常见的注意事项,帮助读者了解协程的运作原理,以

Swoole新特性讲解:更快的高速协程HTTP服务器Swoole新特性讲解:更快的高速协程HTTP服务器Jun 15, 2023 pm 08:16 PM

近年来,随着移动互联网、云计算、大数据等新技术的快速发展,越来越多的企业开始使用PHP构建高并发、高性能的Web应用程序。而传统的LAMP(Linux、Apache、MySQL、PHP)架构,难以满足当前互联网快速发展的需求,因此出现了一些新的PHP框架和工具,比如Swoole。Swoole是一个PHP的网络通信框架,具有协程、异步IO、多进程等优势,可以帮

Go 语言中的协程和 select 语句的联系是什么?Go 语言中的协程和 select 语句的联系是什么?Jun 10, 2023 am 09:45 AM

Go语言中的协程和select语句的联系是什么?随着计算机的发展,我们对于并发编程的需求也越来越迫切。然而,传统的并发编程方法——基于线程和锁——也逐渐变得复杂并容易出错。为了解决这些问题,Go语言引入了一种新的并发编程模型——协程。协程是由语言自己调度的轻量级线程,在协程中,代码的执行是基于非抢占式的协作式调度的,换句话说,每个协程都会执行一段代码

Swoole进阶:如何使用协程优化数据库查询Swoole进阶:如何使用协程优化数据库查询Jun 15, 2023 pm 09:52 PM

随着Web应用程序的迅速发展,开发者们不仅要关注应用程序的功能和可靠性,还要考虑应用程序的性能。而数据库操作一直是Web应用程序的一个瓶颈之一。传统的数据库查询方式通常是通过多线程或者多进程来实现,这个方法效率低下,而且不容易管理。而Swoole的协程特性可以用来优化数据库查询,并提高应用程序的性能。Swoole是一款PHP的高性能网络框架。它有一个非常重要

Swoole中如何高效使用协程?Swoole中如何高效使用协程?Jun 13, 2023 pm 07:15 PM

Swoole中如何高效使用协程?协程是一种轻量级的线程,可以在同一个进程内并发执行大量的任务。Swoole作为一个高性能的网络通信框架,对协程提供了支持。Swoole的协程不仅仅是简单的协程调度器,还提供了很多强大的功能,如协程池、协程原子操作,以及各种网络编程相关的协程封装等等,这些功能都可以帮助我们更高效地开发网络应用。在Swoole中使用协程有很多好处

协程编程与Swoole实战:实现高并发接口设计协程编程与Swoole实战:实现高并发接口设计Jun 13, 2023 pm 06:39 PM

随着互联网应用的普及,越来越多的应用需要面对高并发的挑战。传统的线程池或进程池方式已经不能满足这种情况下的需求。协程编程技术成为了一种解决高并发问题的有效方式,而Swoole则是目前应用最广泛的协程框架之一。本文将介绍协程编程的基本概念和原理,以及如何使用Swoole框架进行高并发接口设计。我们将以一个简单的Web服务为例,分步骤介绍如何使用协程和Swool

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境