この記事では、主に PHP のコルーチンとブロックについての理解と考え方を、サンプル コードを通じて詳しく紹介しています。PHP を学習または使用する人にとって、一定の参考となる価値があります。必要な方は以下を参照してください。一緒に学びましょう。
前書き
この記事では主に、PHP のコルーチンとブロックについての理解と考え方を紹介し、参考と学習のために共有します。以下では多くのことを説明しません。詳細な紹介を見てみましょう。
プロセス、スレッド、コルーチン
プロセス、スレッド、コルーチンについては、非常に詳細で充実したブログや学習リソースがありますので、ここでは詳しく説明しません。
プロセスには独自の独立したヒープとスタックがあり、ヒープもスタックも共有しません。プロセスはオペレーティング システムによってスケジュールされます。
スレッドには独自の独立したスタックと共有ヒープがあります。ヒープは共有されますが、スレッドもオペレーティング システムによってスケジュールされます (標準スレッドは共有されます)。
コルーチンはスレッドと同様にヒープを共有しますが、スタックは共有しません。コルーチンは、コルーチンのコード内でプログラマによって明示的にスケジュールされます。
PHP におけるコルーチン yield の基本的な実装
yield の基本的な実装はジェネレーター クラスであり、イテレーター クラスはイテレーター インターフェイスの実装です。上記の分析については、PHP 公式ドキュメントを参照してください。
http://php.net/manual/zh/clas...
そしてこの詳細なドキュメント:
http://www.jb51.net/article/39424_all.htm
これを使用して達成しますコルーチンのマルチタスク スケジューリングに基づいた例を示し、ブロックに関する私の考えをいくつかお話します。
単純なスケジュールされた実行タスクのカスタマイズの例:
(この例は、上記の Brother Niao によって実装されたコルーチン スケジューリング コードに依存する必要があります)
Generator implements Iterator { public mixed current ( void ) // 返回当前产生的值 public mixed key ( void ) // 返回当前产生的键 public void next ( void ) // 生成器继续执行 public void rewind ( void ) // 重置迭代器,如果迭代已经开始了,这里会抛出一个异常。 // renwind的执行将会导致第一个yield被执行, 并且忽略了他的返回值. public mixed send ( mixed $value ) // 向生成器中传入一个值,并且当做 yield 表达式的结果,然后继续执行生成器。如果当这个方法被调用时,生成器 // 不在 yield 表达式,那么在传入值之前,它会先运行到第一个 yield 表达式。 public void throw ( Exception $exception ) // 向生成器中抛入一个异常 public bool valid ( void ) // 检查迭代器是否被关闭 public void __wakeup ( void ) // 序列化回调,抛出一个异常以表示生成器不能被序列化。 }上記の実装は次のとおりです:
2 つを生成しますタスクを並列実行し、実行中に各タスクのブロックを数秒間シミュレートします。
- コルーチンが切り替わるときにスムーズに切り替えることができ、タスクのブロックは相互に影響しません。
-
なぜ上記のことをしなければならないのでしょうか?コルーチンの実装は非常に強力で興味深いものであり、並列マルチタスクを可能にすることができますが、タスクの 1 つでシステム関数
sleep()
を呼び出すと、ブロック タスクによって実行が妨げられることがわかりました。コルーチンの切り替え 実際、これはコルーチンの実装原則にも当てはまります。 - 次に、コルーチンのブロックもシミュレートしたいと思いますが、それが実現可能かどうかを確認するためにブロックを発生させません。 PHP 自体は、コルーチン呼び出しをサポートするためのジェネレーターのみを提供します。拡張機能に依存しない場合は、Java ほど強力ではなく、サブスレッドを開くことで実装できます。 Javaのサブスレッドは独立して実行され、お互いにブロックしない印象があるので、PHPではマルチスレッドに近い仕組みが実装できるので、呼び出し処理中にノンブロッキングを実現できるのではないかと考えています。
sleep()
のブロックによる誤解でした。本当にノンブロッキングを実現するには、言い換えれば、非同期に実装するには、基礎となる言語に依存する必要があります。 後で、私は真実を理解しました。特定のメソッドまたは関数は実行中にブロックされるため、現在のメソッドをカスタムメソッドに置き換えて、(コルーチンのスケジューリング全体と比較して)非ブロックにします。それだけでは十分ではありません。 ?たとえば、上記のスケジュールされた実行を自分で実装しました。
一方、コルーチン スケジューリング自体の目的は、タスクの実行プロセスをできるだけ小さく切り分けて、実行を迅速に切り替えて並列処理を実現することです。この観点から、コルーチンはプログラミングのアイデアともみなされる必要があります。
sleep()
的时候,阻塞任务会阻止协程切换,其实从协程的实现原理上来书也是这么回事。
那么,我也就想模拟协程阻塞,但是不产生阻塞看是否可行。PHP本身只提供了生成器为协程调用提供了支撑,如果不依赖扩展,没有提供多线程的程序实现方式,没有java那么强大,可以开子线程进行实现。
我印象中java的子线程是独立执行且不会相互阻塞的,所以我在想,PHP既然可以实现类似于多线程这样的机制,那么能不能实现调用过程中非阻塞呢?
经过这样一个实现和思考,一开始是陷入了一个误区的,是由于PHP原生函数 sleep()
以下は、実行のためにプログラムをできるだけ小さな部分に分割する例です:
class timer { private $start = 0; // 定时开始时间 private $timer; // 间隔的时间差,单位秒 private $value = 0; // 产生的结果值 private $callback; // 异步回调 private $isEnd = false; // 当前定时器任务是否结束 public function __construct($timer,callable $callback) { $this->start = time(); $this->timer = $timer; $this->callback = $callback; } public function run() { if($this->valid()) { $callback = $this->callback; $callback($this->value ++,$this); $this->start = time(); } } /** * 定时执行检查 */ public function valid() { $end = time(); if($end - $this->start >= $this->timer) { return true; } else { return false; } } public function setEnd($isEnd) { $this->isEnd = $isEnd; } public function getEnd() { return $this->isEnd; } } /** * 模拟阻塞的协程1 * */ function taskObject1() { $timer = new timer(1,function($value,timer $timer) { if($value >= 5) { $timer->setEnd(true); } echo '<br>'.'A '.$value; }); $tid = (yield getTaskId()); while (true) { if($timer->getEnd() == true) { break; } yield $timer->run(); } } /** * 模拟阻塞的协程2 * */ function taskObject2() { $timer = new timer(2,function($value,timer $timer) { if($value >= 3) { $timer->setEnd(true); } echo '<br>'.'B '.$value; }); $tid = (yield getTaskId()); while (true) { if($timer->getEnd() == true) { break; } yield $timer->run(); } } $scheduler = new Scheduler; $scheduler->newTask(taskObject1()); $scheduler->newTask(taskObject2()); $scheduler->run();この例では、range を使用して大きな整数配列を生成する元の方法から、スライス実行に切り替えます。つまり、トラバース時に指定された値を取得するということですが、コードの観点から見ると、メモリ消費量は以前に比べて非常に少なくなります。
以上がPHP におけるコルーチンとブロッキングの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

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

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

Dreamweaver Mac版
ビジュアル Web 開発ツール
