{"id":164173,"date":"2012-12-28T09:03:03","date_gmt":"2012-12-28T05:03:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=164173"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=164173","title":{"rendered":"<span class=\"post_title\">Coroutines \u0432 PHP \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438<\/span>"},"content":{"rendered":"<div class=\"content html_format\">       \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u043e\u0432\u043e\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u0432 PHP 5.5 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d (\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c). \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u043b\u0438 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u044b \u0432 <a href=\"http:\/\/de2.php.net\/manual\/en\/language.generators.overview.php\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a> \u0438 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 <a href=\"http:\/\/blog.ircmaxell.com\/2012\/07\/what-generators-can-do-for-you.html\">\u044d\u0442\u043e\u043c<\/a> \u0438\u043b\u0438 \u0432 <a href=\"http:\/\/sheriframadan.com\/2012\/10\/test-drive-php-5-5-a-sneak-peek\/#generators\">\u044d\u0442\u043e\u043c<\/a>). \u0421\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u042d\u0442\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0439, \u043d\u043e \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0441 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0441\u0442\u0443\u043f\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u043e\u0432. \u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u043d\u0430\u0435\u0442\u0435 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u0442\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0430\u0437\u0434\u0435\u043b\u0443 \u00ab\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c\u00bb.<\/p>\n<h4>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b<\/h4>\n<p>  \u0421\u0443\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0430 <em>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/em>, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c. \u0418\u043b\u0438, \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u0430\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>xrange()<\/code>:  <\/p>\n<pre><code>function xrange($start, $end, $step = 1) {     for ($i = $start; $i &lt;= $end; $i += $step) {         yield $i;     } }  foreach (xrange(1, 1000000) as $num) {     echo $num, &quot;\\n&quot;; }<\/code><\/pre>\n<p>  \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0432 PHP, <code>range()<\/code>. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>range()<\/code> \u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0431\u044b \u0432\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u0430 \u0447\u0438\u0441\u0435\u043b, \u0430 <code>xrange()<\/code> \u0432\u0435\u0440\u043d\u0435\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0447\u0438\u0441\u043b\u0430, \u043d\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043d\u0438\u043c\u0438.<\/p>\n<p>  \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043d\u0430\u0431\u043e\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044f \u0438\u0445 \u0432\u0441\u0435\u0445 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c. \u0412\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 <em>\u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c\u0438<\/em> \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0431\u0435\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0441\u043e\u0437\u0434\u0430\u0432 \u043a\u043b\u0430\u0441\u0441 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>Iterator<\/code>. \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u044d\u0442\u043e (\u0433\u043e\u0440\u0430\u0437\u0434\u043e) \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0437\u0430\u043d\u044f\u0442\u0438\u0435\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u044f\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430.<\/p>\n<h4>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043a\u0430\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043a \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c, \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0438\u0437\u043d\u0443\u0442\u0440\u0438: \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u2014 \u044d\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>yield<\/code>.<\/p>\n<p>  \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 <code>xrange(1, 1000000)<\/code> \u2014 \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u0437 \u0442\u0435\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>xrange<\/code> \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u043e. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, PHP \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Generator<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>Iterator<\/code>:  <\/p>\n<pre><code>&lt;?php  $range = xrange(1, 1000000); var_dump($range); \/\/ object(Generator)#1 var_dump($range instanceof Iterator); \/\/ bool(true)<\/code><\/pre>\n<p>  \u041a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0435 <code>$range-&gt;rewind()<\/code> \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>xrange()<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e <code>yield<\/code>. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d <code>$i = $start<\/code> \u0438 \u0437\u0430\u0442\u0435\u043c <code>yield $i<\/code>. \u0427\u0442\u043e \u0431\u044b \u043c\u044b \u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 <code>yield<\/code>, \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>$range-&gt;current()<\/code>.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>$range-&gt;next()<\/code>. \u042d\u0442\u043e \u043e\u043f\u044f\u0442\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u0434 \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e <code>yield<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>next()<\/code> \u0438 <code>current()<\/code>, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u0442\u043e\u0439 \u0442\u043e\u0447\u043a\u0438, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 <code>xrange()<\/code> \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 <code>$i<\/code> \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 <code>$end<\/code>. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0442\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u043a\u043e\u043d\u0446\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u0434\u0430. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442, <code>valid()<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>false<\/code> \u0438 \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u0441\u044f.<\/p>\n<h4>\u0421\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h4>\n<p>  \u0413\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043a \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u2014 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0443. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0437 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u043e\u0433\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0434\u0438\u0430\u043b\u043e\u0433, \u0433\u0434\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0447\u0442\u043e-\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0443.<\/p>\n<p>  \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 <code>send()<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>next()<\/code>. \u041f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u0432\u043e\u0442 \u044d\u0442\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430:  <\/p>\n<pre><code>function logger($fileName) {     $fileHandle = fopen($fileName, 'a');     while (true) {         fwrite($fileHandle, yield . &quot;\\n&quot;);     } }  $logger = logger(__DIR__ . '\/log'); $logger-&gt;send('Foo'); $logger-&gt;send('Bar');<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0437\u0434\u0435\u0441\u044c <code>yield<\/code> \u043d\u0435 \u043a\u0430\u043a statement (\u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>return<\/code> \u0438\u043b\u0438 <code>echo<\/code>), \u0430 \u043a\u0430\u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0438\u0442 \u0442\u043e, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0441\u043b\u0430\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>send()<\/code>. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <code>yield<\/code> \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0438\u0442 <code>&quot;Foo&quot;<\/code>, \u0430 \u043f\u043e\u0442\u043e\u043c <code>&quot;Bar&quot;<\/code>.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043a\u0430\u043a <code>yield<\/code> \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f. \u041d\u043e \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0430 \u0442\u0438\u043f\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:  <\/p>\n<pre><code>function gen() {     $ret = (yield 'yield1');     var_dump($ret);     $ret = (yield 'yield2');     var_dump($ret); }  $gen = gen(); var_dump($gen-&gt;current());    \/\/ string(6) &quot;yield1&quot; var_dump($gen-&gt;send('ret1')); \/\/ string(4) &quot;ret1&quot;   (the first var_dump in gen)                               \/\/ string(6) &quot;yield2&quot; (the var_dump of the -&gt;send() return value) var_dump($gen-&gt;send('ret2')); \/\/ string(4) &quot;ret2&quot;   (again from within gen)                               \/\/ NULL               (the return value of -&gt;send())<\/code><\/pre>\n<p>  \u0422\u043e\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u044b\u0432\u043e\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043a\u043e\u0434 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0441\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0449\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0430\u0448\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043f\u0435\u0440\u0432\u043e\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043a\u043e\u0431\u043e\u043a \u0432\u043e\u043a\u0440\u0443\u0433 <code>yield<\/code> \u2014 \u044d\u0442\u043e \u043d\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u044c. \u042d\u0442\u0438 \u0441\u043a\u043e\u0431\u043a\u0438 \u043d\u0443\u0436\u043d\u044b \u043d\u0430\u043c \u043f\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c (\u044f \u0434\u0430\u0436\u0435 \u043f\u043e\u0434\u0443\u043c\u044b\u0432\u0430\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u043e\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435). \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438, \u0447\u0442\u043e <code>current()<\/code> \u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0431\u0435\u0437 \u0432\u044b\u0437\u043e\u0432\u0430 <code>rewind()<\/code>. <code>rewind()<\/code>, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u044f\u0432\u043d\u043e.<\/p>\n<h4>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c<\/h4>\n<p>  \u0415\u0441\u043b\u0438 \u0447\u0438\u0442\u0430\u044f \u043f\u0440\u0438\u043c\u0435\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>logger()<\/code>, \u0432\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u043b\u0438 \u00ab\u0417\u0430\u0447\u0435\u043c \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443? \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441?\u00bb, \u0442\u043e\u0433\u0434\u0430 \u0432\u044b \u0431\u044b\u043b\u0438 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043f\u0440\u0430\u0432\u044b. \u0422\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043b\u0438\u0448\u044c \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442, \u043a\u0430\u043a \u044d\u0442\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u0432 \u043d\u0435\u043c \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u0438\u0447\u0438\u043d, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b. \u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u0432\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0438, \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u2014 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0449\u043d\u0430\u044f \u0448\u0442\u0443\u043a\u0430, \u043d\u043e \u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u043d\u044c \u0440\u0435\u0434\u043a\u043e \u0438 \u0447\u0430\u0441\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0438 \u043d\u0435 \u043d\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439.<\/p>\n<p>  \u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u043c\u0443\u043b\u044c\u0442\u0438\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b. \u0421\u0443\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u041d\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 (\u043f\u0440\u0438\u043c. \u043f\u0435\u0440. \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0432 \u0432\u0430\u043a\u0443\u0443\u043c\u0435) \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u043e\u0434\u0438\u043d \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u0438 \u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u00ab\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c\u00bb.<\/p>\n<p>  \u00ab\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f\u00bb \u044d\u0442\u0430 \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u043d\u0430 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0434\u043e\u0431\u0440\u043e\u0432\u043e\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0442 \u043c\u043e\u0433 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u0415\u0441\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c, \u0433\u0434\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443. \u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0432 \u0440\u0430\u043d\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Windows (\u0434\u043e Win95) \u0438 Mac OS, \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430 \u2014 \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0435\u0441\u044c \u043d\u0430 \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0434\u043e\u0431\u0440\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0442\u0434\u0430\u043b\u0430 \u043f\u043e\u0442\u043e\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0442\u043e \u043b\u044e\u0431\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043a\u043a\u0443\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c CPU.<\/p>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c \u0437\u0430\u0434\u0430\u0447: <code>yield<\/code> \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0434\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 \u0438 \u043e\u043d \u043c\u043e\u0433 \u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, <code>yield<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c.<\/p>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043d\u043a\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 \u0432\u043e\u043a\u0440\u0443\u0433 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430:  <\/p>\n<pre><code>class Task {     protected $taskId;     protected $coroutine;     protected $sendValue = null;     protected $beforeFirstYield = true;      public function __construct($taskId, Generator $coroutine) {         $this-&gt;taskId = $taskId;         $this-&gt;coroutine = $coroutine;     }      public function getTaskId() {         return $this-&gt;taskId;     }      public function setSendValue($sendValue) {         $this-&gt;sendValue = $sendValue;     }      public function run() {         if ($this-&gt;beforeFirstYield) {             $this-&gt;beforeFirstYield = false;             return $this-&gt;coroutine-&gt;current();         } else {             $retval = $this-&gt;coroutine-&gt;send($this-&gt;sendValue);             $this-&gt;sendValue = null;             return $retval;         }     }      public function isFinished() {         return !$this-&gt;coroutine-&gt;valid();     } }<\/code><\/pre>\n<p>  \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (<code>taskId<\/code>). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <code>setSendValue()<\/code> \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 (\u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u043f\u043e\u0437\u0436\u0435). \u041c\u0435\u0442\u043e\u0434 <code>run()<\/code> \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>send()<\/code> \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b.<br \/>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0437\u0430\u0447\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u043b\u0430\u0433 <code>beforeFirstYield<\/code>, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:  <\/p>\n<pre><code>function gen() {     yield 'foo';     yield 'bar'; }  $gen = gen(); var_dump($gen-&gt;send('something'));  \/\/ \u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f send(), \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0432\u044b\u043c yield \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 rewind() \/\/ \u0412\u043e\u0442 \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c: $gen-&gt;rewind(); var_dump($gen-&gt;send('something'));  \/\/ rewind() \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u0442 \u043a \u043f\u0435\u0440\u0432\u043e\u043c\u0443 yield (\u0438 \u043e\u043f\u0443\u0441\u0442\u0438\u0442 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435), send() \/\/ \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u0442 \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u043c\u0443 yield (\u0438 var_dump-\u043d\u0435\u0442 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435). \/\/ \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/code><\/pre>\n<p>  \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>beforeFirstYield<\/code> \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u043d\u0430\u0442\u044c, \u0431\u044b\u043b \u043b\u0438 \u0443\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d \u043f\u0435\u0440\u0432\u044b\u0439 yield.<\/p>\n<p>  \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u0432\u0441\u0435\u043c \u0442\u0430\u0441\u043a\u0430\u043c:  <\/p>\n<pre><code>class Scheduler {     protected $maxTaskId = 0;     protected $taskMap = []; \/\/ taskId =&gt; task     protected $taskQueue;      public function __construct() {         $this-&gt;taskQueue = new SplQueue();     }      public function newTask(Generator $coroutine) {         $tid = ++$this-&gt;maxTaskId;         $task = new Task($tid, $coroutine);         $this-&gt;taskMap[$tid] = $task;         $this-&gt;schedule($task);         return $tid;     }      public function schedule(Task $task) {         $this-&gt;taskQueue-&gt;enqueue($task);     }      public function run() {         while (!$this-&gt;taskQueue-&gt;isEmpty()) {             $task = $this-&gt;taskQueue-&gt;dequeue();             $task-&gt;run();              if ($task-&gt;isFinished()) {                 unset($this-&gt;taskMap[$task-&gt;getTaskId()]);             } else {                 $this-&gt;schedule($task);             }         }     } }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>newTask()<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043a\u043b\u0430\u0434\u0435\u0442 \u0435\u0435 \u0432 <code>taskMap<\/code>. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043e\u043d \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c <code>taskQueue<\/code>. \u041c\u0435\u0442\u043e\u0434 <code>run()<\/code> \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u044d\u0442\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438. \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u2014 \u043e\u043d\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f, \u0438\u043d\u0430\u0447\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441 \u0434\u0432\u0443\u043c\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 (\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u044b\u043c\u0438) \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438:  <\/p>\n<pre><code>function task1() {     for ($i = 1; $i &lt;= 10; ++$i) {         echo &quot;This is task 1 iteration $i.\\n&quot;;         yield;     } }  function task2() {     for ($i = 1; $i &lt;= 5; ++$i) {         echo &quot;This is task 2 iteration $i.\\n&quot;;         yield;     } }  $scheduler = new Scheduler;  $scheduler-&gt;newTask(task1()); $scheduler-&gt;newTask(task2());  $scheduler-&gt;run();<\/code><\/pre>\n<p>  \u041e\u0431\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u044f\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0438 \u043e\u0442\u0434\u0430\u044e\u0442 \u043f\u043e\u0442\u043e\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443. \u0412\u043e\u0442 \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e:  <\/p>\n<pre>This is task 1 iteration 1. This is task 2 iteration 1. This is task 1 iteration 2. This is task 2 iteration 2. This is task 1 iteration 3. This is task 2 iteration 3. This is task 1 iteration 4. This is task 2 iteration 4. This is task 1 iteration 5. This is task 2 iteration 5. This is task 1 iteration 6. This is task 1 iteration 7. This is task 1 iteration 8. This is task 1 iteration 9. This is task 1 iteration 10.<\/pre>\n<h4>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c<\/h4>\n<p>  \u0418\u0442\u0430\u043a, \u043d\u0430\u0448 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u0443\u043d\u043a\u0442\u0443 \u0432 \u043f\u043e\u0432\u0435\u0441\u0442\u043a\u0435 \u0434\u043d\u044f: \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u0441\u043f\u043e\u0441\u043e\u0431, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439: \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b (syscall, \u0441\u0438\u0441\u043a\u043e\u043b). \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0441\u0438\u0441\u043a\u043e\u043b\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0435\u0439, \u043d\u0435\u0436\u0435\u043b\u0438 \u0441\u0430\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u0431<em>\u043e<\/em>\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0443\u0431\u0438\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b) \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u044f\u0434\u0440\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u043e \u043c\u043e\u0433\u043b\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0418\u0437\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<p>  \u041d\u0430\u0448 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b: \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447\u0435 (\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0441 \u043d\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e), \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 <code>yield<\/code>. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, <code>yield<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0438 \u043a\u0430\u043a \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e (\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c) \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0441\u043a\u043e\u043b, \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443 \u043d\u0430\u0434 <code>callable<\/code>:  <\/p>\n<pre><code>class SystemCall {     protected $callback;      public function __construct(callable $callback) {         $this-&gt;callback = $callback;     }      public function __invoke(Task $task, Scheduler $scheduler) {         $callback = $this-&gt;callback; \/\/ Can't call it directly in PHP :\/         return $callback($task, $scheduler);     } }<\/code><\/pre>\n<p>  \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f, \u043a\u0430\u043a \u043b\u044e\u0431\u0430\u044f \u0434\u0440\u0443\u0433\u0430\u044f <code>callable<\/code>, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c, \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>run()<\/code> \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430:  <\/p>\n<pre><code>public function run() {     while (!$this-&gt;taskQueue-&gt;isEmpty()) {         $task = $this-&gt;taskQueue-&gt;dequeue();         $retval = $task-&gt;run();          if ($retval instanceof SystemCall) {             $retval($task, $this);             continue;         }          if ($task-&gt;isFinished()) {             unset($this-&gt;taskMap[$task-&gt;getTaskId()]);         } else {             $this-&gt;schedule($task);         }     } }<\/code><\/pre>\n<p>  \u041d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u0441\u043a\u043e\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0434\u0430\u0447\u0438:  <\/p>\n<pre><code>function getTaskId() {     return new SystemCall(function(Task $task, Scheduler $scheduler) {         $task-&gt;setSendValue($task-&gt;getTaskId());         $scheduler-&gt;schedule($task);     }); }<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0441\u0442\u0430\u0432\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0414\u043b\u044f \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e (\u0432\u044b \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u043f\u043e\u0447\u0435\u043c\u0443 \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435).<br \/>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 \u043d\u043e\u0432\u044b\u0439 \u0441\u0438\u0441\u043a\u043e\u043b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:  <\/p>\n<pre><code>function task($max) {     $tid = (yield getTaskId()); \/\/ &lt;-- here's the syscall!     for ($i = 1; $i &lt;= $max; ++$i) {         echo &quot;This is task $tid iteration $i.\\n&quot;;         yield;     } }  $scheduler = new Scheduler;  $scheduler-&gt;newTask(task(10)); $scheduler-&gt;newTask(task(5));  $scheduler-&gt;run();<\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u0442\u043e\u0442 \u0436\u0435 \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440. \u0415\u0449\u0435 \u043f\u0430\u0440\u0430 \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0438 \u0443\u0431\u0438\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447:  <\/p>\n<pre><code>function newTask(Generator $coroutine) {     return new SystemCall(         function(Task $task, Scheduler $scheduler) use ($coroutine) {             $task-&gt;setSendValue($scheduler-&gt;newTask($coroutine));             $scheduler-&gt;schedule($task);         }     ); }  function killTask($tid) {     return new SystemCall(         function(Task $task, Scheduler $scheduler) use ($tid) {             $task-&gt;setSendValue($scheduler-&gt;killTask($tid));             $scheduler-&gt;schedule($task);         }     ); }<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>killTask<\/code> \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u043a\u0438\u0435:  <\/p>\n<pre><code>public function killTask($tid) {     if (!isset($this-&gt;taskMap[$tid])) {         return false;     }      unset($this-&gt;taskMap[$tid]);      \/\/ \u042d\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u0440\u0438\u0432\u043e \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c,     \/\/ \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043d\u043e \u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u044d\u0442\u043e \u043d\u0430 \u043f\u043e\u0442\u043e\u043c     foreach ($this-&gt;taskQueue as $i =&gt; $task) {         if ($task-&gt;getTaskId() === $tid) {             unset($this-&gt;taskQueue[$i]);             break;         }     }      return true; }<\/code><\/pre>\n<p>  \u041c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438:  <\/p>\n<pre><code>function childTask() {     $tid = (yield getTaskId());     while (true) {         echo &quot;Child task $tid still alive!\\n&quot;;         yield;     } }  function task() {     $tid = (yield getTaskId());     $childTid = (yield newTask(childTask()));      for ($i = 1; $i &lt;= 6; ++$i) {         echo &quot;Parent task $tid iteration $i.\\n&quot;;         yield;          if ($i == 3) yield killTask($childTid);     } }  $scheduler = new Scheduler; $scheduler-&gt;newTask(task()); $scheduler-&gt;run();<\/code><\/pre>\n<p>  \u0412\u044b\u0432\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:  <\/p>\n<pre>Parent task 1 iteration 1. Child task 2 still alive! Parent task 1 iteration 2. Child task 2 still alive! Parent task 1 iteration 3. Child task 2 still alive! Parent task 1 iteration 4. Parent task 1 iteration 5. Parent task 1 iteration 6.<\/pre>\n<p>  \u0414\u043e\u0447\u0435\u0440\u043d\u044f\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u0440\u0435\u0445 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439, \u0442\u043e\u0433\u0434\u0430 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u00abChild task still alive!\u00bb. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0438 \u0440\u0435\u0431\u0435\u043d\u043e\u043a, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043e\u0447\u0435\u0440\u043d\u044f\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u0430\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u0443\u0436\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c. \u0418\u043b\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u044f\u044f \u043c\u043e\u0436\u0435\u0442 \u0434\u0430\u0436\u0435 \u0443\u0431\u0438\u0442\u044c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e. \u041c\u044b \u0431\u044b \u043c\u043e\u0433\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u043c \u0438 \u0440\u0435\u0431\u0435\u043d\u043a\u043e\u043c, \u043d\u043e \u043d\u0435 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>  \u0415\u0441\u0442\u044c \u0435\u0449\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>wait<\/code> (\u0436\u0434\u0430\u0442\u044c \u043f\u043e\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e), <code>exec<\/code> (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0435\u0442, \u043a\u0430\u043a\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u044c) \u0438 <code>fork<\/code> (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u043e\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438). \u041a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u043a\u043b\u0430\u0441\u0441\u043d\u0430\u044f \u0444\u0438\u0447\u0430 \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0435\u0435 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<h4>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435<\/h4>\n<p>  \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043b\u0430\u0441\u0441\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u2014 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0434\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u0441\u043b\u0443\u0448\u0430\u044e\u0449\u0430\u044f \u0441\u043e\u043a\u0435\u0442 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043a\u0430\u043a \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u0441\u043e\u043a\u0435\u0442\u0430\u0445, \u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 PHP \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c PHP \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044d\u0442\u043e, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u043e: \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0443 \u0441\u043e\u043a\u0435\u0442\u0430, \u00ab\u0433\u043e\u0442\u043e\u0432\u00bb \u043b\u0438 \u043e\u043d, \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u0433\u043e. \u0427\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0441\u043e\u043a\u0435\u0442\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>stream_select()<\/code>.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u043d\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u043e\u043a\u0435\u0442 \u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043b\u0438\u0431\u043e \u0447\u0442\u0435\u043d\u0438\u044f, \u043b\u0438\u0431\u043e \u0437\u0430\u043f\u0438\u0441\u0438:  <\/p>\n<pre><code>function waitForRead($socket) {     return new SystemCall(         function(Task $task, Scheduler $scheduler) use ($socket) {             $scheduler-&gt;waitForRead($socket, $task);         }     ); }  function waitForWrite($socket) {     return new SystemCall(         function(Task $task, Scheduler $scheduler) use ($socket) {             $scheduler-&gt;waitForWrite($socket, $task);         }     ); }<\/code><\/pre>\n<p>  \u042d\u0442\u0438 \u0441\u0438\u0441\u043a\u043e\u043b\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430:  <\/p>\n<pre><code>&lt;?php  \/\/ resourceID =&gt; [socket, tasks] protected $waitingForRead = []; protected $waitingForWrite = [];  public function waitForRead($socket, Task $task) {     if (isset($this-&gt;waitingForRead[(int) $socket])) {         $this-&gt;waitingForRead[(int) $socket][1][] = $task;     } else {         $this-&gt;waitingForRead[(int) $socket] = [$socket, [$task]];     } }  public function waitForWrite($socket, Task $task) {     if (isset($this-&gt;waitingForWrite[(int) $socket])) {         $this-&gt;waitingForWrite[(int) $socket][1][] = $task;     } else {         $this-&gt;waitingForWrite[(int) $socket] = [$socket, [$task]];     } }<\/code><\/pre>\n<p>  \u041f\u043e\u043b\u044f <code>waitingForRead<\/code> \u0438 <code>waitingForWrite<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043a\u0435\u0442\u044b \u0438 \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a \u043d\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0438. \u0421\u0430\u043c\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b \u043b\u0438 \u0441\u043e\u043a\u0435\u0442\u044b \u0438 \u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u0442\u0430\u0441\u043a\u0438:  <\/p>\n<pre><code>protected function ioPoll($timeout) {     $rSocks = [];     foreach ($this-&gt;waitingForRead as list($socket)) {         $rSocks[] = $socket;     }      $wSocks = [];     foreach ($this-&gt;waitingForWrite as list($socket)) {         $wSocks[] = $socket;     }      $eSocks = []; \/\/ dummy      if (!stream_select($rSocks, $wSocks, $eSocks, $timeout)) {         return;     }      foreach ($rSocks as $socket) {         list(, $tasks) = $this-&gt;waitingForRead[(int) $socket];         unset($this-&gt;waitingForRead[(int) $socket]);          foreach ($tasks as $task) {             $this-&gt;schedule($task);         }     }      foreach ($wSocks as $socket) {         list(, $tasks) = $this-&gt;waitingForWrite[(int) $socket];         unset($this-&gt;waitingForWrite[(int) $socket]);          foreach ($tasks as $task) {             $this-&gt;schedule($task);         }     } }<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>stream_select<\/code> \u0431\u0435\u0440\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u0447\u0442\u0435\u043d\u0438\u044f, \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f (\u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439). \u041c\u0430\u0441\u0441\u0438\u0432\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0432 \u043d\u0438\u0445 \u043b\u0438\u0448\u044c \u0442\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c \u0438 \u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u043a\u0435\u0442\u0430\u043c\u0438.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434:  <\/p>\n<pre><code>protected function ioPollTask() {     while (true) {         if ($this-&gt;taskQueue-&gt;isEmpty()) {             $this-&gt;ioPoll(null);         } else {             $this-&gt;ioPoll(0);         }         yield;     } }<\/code><\/pre>\n<p>  \u042d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430\u0434\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <code>$this-&gt;newTask($this-&gt;ioPollTask())<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <code>run()<\/code>. \u0422\u043e\u0433\u0434\u0430 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u043b\u044e\u0431\u0430\u044f \u0434\u0440\u0443\u0433\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u043e\u043a\u0435\u0442\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438. \u041c\u0435\u0442\u043e\u0434 <code>ioPollTask<\/code> \u0432\u044b\u0437\u043e\u0432\u0435\u0442 <code>ioPoll<\/code> \u0441 \u043d\u0443\u043b\u0435\u0432\u044b\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 stream_select \u0432\u0435\u0440\u043d\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0440\u0430\u0437\u0443, \u0431\u0435\u0437 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447 \u043f\u0443\u0441\u0442\u0430, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>null<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430, \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>stream_select<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c, \u043f\u043e\u043a\u0430 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u043b\u0438, \u0442\u043e \u0441\u044a\u0435\u043b\u0438 \u0431\u044b \u0432\u0435\u0441\u044c CPU (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u044f\u0434\u0440\u043e), \u0442.\u043a. \u044d\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0430\u0441\u044c \u0431\u044b \u0432 \u0446\u0438\u043a\u043b\u0435 \u0440\u0430\u0437 \u0437\u0430 \u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043a\u0430 \u043a\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u0431\u044b.<\/p>\n<p>  \u0421\u0430\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e:  <\/p>\n<pre><code>function server($port) {     echo &quot;Starting server at port $port...\\n&quot;;      $socket = @stream_socket_server(&quot;tcp:\/\/localhost:$port&quot;, $errNo, $errStr);     if (!$socket) throw new Exception($errStr, $errNo);      stream_set_blocking($socket, 0);      while (true) {         yield waitForRead($socket);         $clientSocket = stream_socket_accept($socket, 0);         yield newTask(handleClient($clientSocket));     } }  function handleClient($socket) {     yield waitForRead($socket);     $data = fread($socket, 8192);      $msg = &quot;Received following request:\\n\\n$data&quot;;     $msgLength = strlen($msg);      $response = &lt;&lt;&lt;RES HTTP\/1.1 200 OK\\r Content-Type: text\/plain\\r Content-Length: $msgLength\\r Connection: close\\r \\r $msg RES;      yield waitForWrite($socket);     fwrite($socket, $response);      fclose($socket); }  $scheduler = new Scheduler; $scheduler-&gt;newTask(server(8000)); $scheduler-&gt;run();<\/code><\/pre>\n<p>  \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430 8000 \u043f\u043e\u0440\u0442 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u043b\u0438\u0431\u043e \u00ab\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435\u00bb \u0431\u044b\u043b\u043e \u0431\u044b \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435 (\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u2014 \u043d\u0435 \u0442\u0435\u043c\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438).<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u044b\u0442\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0447\u0435\u0433\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 <code>ab -n 10000 -c 100 localhost:8000\/<\/code>. \u0422\u0430\u043a \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c 10000 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, 100 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 \u0441\u043b\u0430\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u043e\u0442\u0432\u0435\u0442 \u0437\u0430 10 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434. \u041d\u043e \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c <em>\u043e\u0447\u0435\u043d\u044c<\/em> \u0434\u043e\u043b\u0433\u043e (\u0432 \u0440\u0430\u0439\u043d\u043e\u0435 5 \u0441\u0435\u043a\u0443\u043d\u0434), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u0449\u0430\u044f \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0430\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0433\u043e 2000 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443. \u0421 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>-c 500<\/code>) \u0441\u043a\u0440\u0438\u043f\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u043d\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u00abConnections reset by peer\u00bb.<\/p>\n<h4>\u0412\u044b\u043d\u0435\u0441\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h4>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0430\u0447\u043d\u0435\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043d\u0430\u0448 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u0432\u044b \u0432\u0441\u043a\u043e\u0440\u0435 \u043d\u0430\u0442\u043a\u043d\u0435\u0442\u0435\u0441\u044c \u043d\u0430 \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443: \u043c\u044b \u0447\u0430\u0441\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u043b\u0438 \u043a\u043e\u0434, \u0432\u044b\u043d\u043e\u0441\u044f \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043a\u0443\u0441\u043a\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0438\u0445. \u041d\u043e \u0441 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u044d\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:  <\/p>\n<pre><code>function echoTimes($msg, $max) {     for ($i = 1; $i &lt;= $max; ++$i) {         echo &quot;$msg iteration $i\\n&quot;;         yield;     } }  function task() {     echoTimes('foo', 10); \/\/ print foo ten times     echo &quot;---\\n&quot;;     echoTimes('bar', 5); \/\/ print bar five times     yield; \/\/ force it to be a coroutine }  $scheduler = new Scheduler; $scheduler-&gt;newTask(task()); $scheduler-&gt;run();<\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 \u043c\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438\u0437 <code>task()<\/code>-\u0430 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0435. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432\u044b\u0437\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043d\u0435\u043c, \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Generator<\/code>. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u0432\u044b\u0437\u043e\u0432\u044b <code>echoTimes()<\/code> \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u044e\u0442, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u044f\u0442 \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0443 \u043d\u0430\u0441 \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443 \u0434\u043b\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0442\u0430\u043a \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434-\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:  <\/p>\n<pre><code>$retval = (yield someCoroutine($foo, $bar));<\/code><\/pre>\n<p>  \u041f\u043e\u0434-\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0442\u043e\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>yield<\/code>:  <\/p>\n<pre><code>yield retval(&quot;I'm return value!&quot;);<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>retval()<\/code> \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u0435\u0440\u0442\u043a\u0443 \u043d\u0430\u0434 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e <em>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435<\/em> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:  <\/p>\n<pre><code>class CoroutineReturnValue {     protected $value;      public function __construct($value) {         $this-&gt;value = $value;     }      public function getValue() {         return $this-&gt;value;     } }  function retval($value) {     return new CoroutineReturnValue($value); }<\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u0443\u044e (\u0441 \u043f\u043e\u0434-\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438) \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e (\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u2014 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430):  <\/p>\n<pre><code>function stackedCoroutine(Generator $gen) {     $stack = new SplStack;      for (;;) {         $value = $gen-&gt;current();          if ($value instanceof Generator) {             $stack-&gt;push($gen);             $gen = $value;             continue;         }          $isReturnValue = $value instanceof CoroutineReturnValue;         if (!$gen-&gt;valid() || $isReturnValue) {             if ($stack-&gt;isEmpty()) {                 return;             }              $gen = $stack-&gt;pop();             $gen-&gt;send($isReturnValue ? $value-&gt;getValue() : NULL);             continue;         }          $gen-&gt;send(yield $gen-&gt;key() =&gt; $value);     } }<\/code><\/pre>\n<p>  \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u043a\u0441\u0438 \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u043c \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043f\u043e\u0434-\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0422\u0430\u043a\u0436\u0435, \u043e\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u0438, \u0435\u0441\u043b\u0438 \u0434\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0435\u0433\u043e. \u041a\u043e\u0433\u0434\u0430 \u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>CoroutineReturnValue<\/code>, \u043e\u043d\u0430 \u0432\u043e\u0437\u044c\u043c\u0435\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0437\u0430\u0434\u0430\u0447\u0430\u0445, \u0441\u0442\u0440\u043e\u043a\u0443 <code>$this-&gt;coroutine = $coroutine;<\/code> \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Task<\/code>, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 <code>$this-&gt;coroutine = stackedCoroutine($coroutine);<\/code>.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u0448 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0447\u0442\u0435\u043d\u0438\u044f, \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0440\u0438\u0435\u043c\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c:  <\/p>\n<pre><code>class CoSocket {     protected $socket;      public function __construct($socket) {         $this-&gt;socket = $socket;     }      public function accept() {         yield waitForRead($this-&gt;socket);         yield retval(new CoSocket(stream_socket_accept($this-&gt;socket, 0)));     }      public function read($size) {         yield waitForRead($this-&gt;socket);         yield retval(fread($this-&gt;socket, $size));     }      public function write($string) {         yield waitForWrite($this-&gt;socket);         fwrite($this-&gt;socket, $string);     }      public function close() {         @fclose($this-&gt;socket);     } }<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c:  <\/p>\n<pre><code>function server($port) {     echo &quot;Starting server at port $port...\\n&quot;;      $socket = @stream_socket_server(&quot;tcp:\/\/localhost:$port&quot;, $errNo, $errStr);     if (!$socket) throw new Exception($errStr, $errNo);      stream_set_blocking($socket, 0);      $socket = new CoSocket($socket);     while (true) {         yield newTask(             handleClient(yield $socket-&gt;accept())         );     } }  function handleClient($socket) {     $data = (yield $socket-&gt;read(8192));      $msg = &quot;Received following request:\\n\\n$data&quot;;     $msgLength = strlen($msg);      $response = &lt;&lt;&lt;RES HTTP\/1.1 200 OK\\r Content-Type: text\/plain\\r Content-Length: $msgLength\\r Connection: close\\r \\r $msg RES;      yield $socket-&gt;write($response);     yield $socket-&gt;close(); }<\/code><\/pre>\n<h4>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h4>\n<p>  \u041a\u0430\u043a \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442, \u0432\u044b \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438, \u0447\u0442\u043e \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c \u043a\u043e\u0434\u0430 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. \u041b\u044e\u0431\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441 \u0441\u043e\u043a\u0435\u0442\u0430\u043c\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0430\u043b\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0448\u0438\u0431\u043a\u0443. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0442\u0430\u043a, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043e\u0447\u0435\u043d\u044c \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u0430 (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u0430\u043c\u0438) \u0438 \u044d\u0442\u043e \u0440\u0430\u0437\u0434\u0443\u043b\u043e \u0431\u044b \u043d\u0430\u0448 \u043a\u043e\u0434 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437.<\/p>\n<p>  \u041d\u043e, \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a \u0434\u043b\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u0446\u0435\u043b\u043e\u043c: \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <em>\u0432\u043d\u0443\u0442\u0440\u044c<\/em> \u043d\u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <code>throw()<\/code>.<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>throw()<\/code> \u0431\u0435\u0440\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0438 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0433\u0434\u0435 \u0441\u0442\u043e\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 yield (\u0447\u044c\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>current()<\/code>):  <\/p>\n<pre><code>function gen() {     echo &quot;Foo\\n&quot;;     try {         yield;     } catch (Exception $e) {         echo &quot;Exception: {$e-&gt;getMessage()}\\n&quot;;     }     echo &quot;Bar\\n&quot;; }  $gen = gen(); $gen-&gt;rewind();                     \/\/ echos &quot;Foo&quot; $gen-&gt;throw(new Exception('Test')); \/\/ echos &quot;Exception: Test&quot;                                     \/\/ and &quot;Bar&quot;<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043a\u043b\u0430\u0441\u0441\u043d\u0430\u044f \u0432\u0435\u0449\u044c, \u0442.\u043a. \u043c\u044b \u043c\u043e\u0436\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u0441\u043a\u043e\u043b\u044b \u0438 \u043f\u043e\u0434-\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432, \u043c\u0435\u0442\u043e\u0434 <code>Scheduler::run()<\/code> \u043d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c:  <\/p>\n<pre><code>if ($retval instanceof SystemCall) {     try {         $retval($task, $this);     } catch (Exception $e) {         $task-&gt;setException($e);         $this-&gt;schedule($task);     }     continue; }<\/code><\/pre>\n<p>  \u0418 \u043a\u043b\u0430\u0441\u0441 <code>Task<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u044b <code>throw()<\/code>:  <\/p>\n<pre><code>class Task {     \/\/ ...     protected $exception = null;      public function setException($exception) {         $this-&gt;exception = $exception;     }      public function run() {         if ($this-&gt;beforeFirstYield) {             $this-&gt;beforeFirstYield = false;             return $this-&gt;coroutine-&gt;current();         } elseif ($this-&gt;exception) {             $retval = $this-&gt;coroutine-&gt;throw($this-&gt;exception);             $this-&gt;exception = null;             return $retval;         } else {             $retval = $this-&gt;coroutine-&gt;send($this-&gt;sendValue);             $this-&gt;sendValue = null;             return $retval;         }     }      \/\/ ... }<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0441\u0438\u0441\u043a\u043e\u043b\u043e\u0432! \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f <code>killTask<\/code>, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u0435\u043d:  <\/p>\n<pre><code>function killTask($tid) {     return new SystemCall(         function(Task $task, Scheduler $scheduler) use ($tid) {             if ($scheduler-&gt;killTask($tid)) {                 $scheduler-&gt;schedule($task);             } else {                 throw new InvalidArgumentException('Invalid task ID!');             }         }     ); }<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c:  <\/p>\n<pre><code>function task() {     try {         yield killTask(500);     } catch (Exception $e) {         echo 'Tried to kill task 500 but failed: ', $e-&gt;getMessage(), &quot;\\n&quot;;     } }<\/code><\/pre>\n<p>  \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0442.\u043a. \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>stackedCoroutine<\/code> \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e, \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0435\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e:  <\/p>\n<pre><code>function stackedCoroutine(Generator $gen) {     $stack = new SplStack;     $exception = null;      for (;;) {         try {             if ($exception) {                 $gen-&gt;throw($exception);                 $exception = null;                 continue;             }              $value = $gen-&gt;current();              if ($value instanceof Generator) {                 $stack-&gt;push($gen);                 $gen = $value;                 continue;             }              $isReturnValue = $value instanceof CoroutineReturnValue;             if (!$gen-&gt;valid() || $isReturnValue) {                 if ($stack-&gt;isEmpty()) {                     return;                 }                  $gen = $stack-&gt;pop();                 $gen-&gt;send($isReturnValue ? $value-&gt;getValue() : NULL);                 continue;             }              try {                 $sendValue = (yield $gen-&gt;key() =&gt; $value);             } catch (Exception $e) {                 $gen-&gt;throw($e);                 continue;             }              $gen-&gt;send($sendValue);         } catch (Exception $e) {             if ($stack-&gt;isEmpty()) {                 throw $e;             }              $gen = $stack-&gt;pop();             $exception = $e;         }     } }<\/code><\/pre>\n<h4>\u041f\u043e\u0434\u0432\u043e\u0434\u044f \u0438\u0442\u043e\u0433<\/h4>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0443\u044e \u043c\u0443\u043b\u044c\u0442\u0438\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043b\u0430\u0442\u044c \u0441\u0438\u0441\u043a\u043e\u043b\u044b, \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a. \u0421\u0430\u043c\u0430\u044f \u043a\u043b\u0430\u0441\u0441\u043d\u0430\u044f \u0432\u0435\u0449\u044c \u0432\u043e \u0432\u0441\u0435\u043c \u044d\u0442\u043e\u043c, \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u0434\u0430\u0436\u0435 \u043d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430, \u0432\u0430\u043c \u043d\u0435 \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u0438\u043b\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0441\u0442\u0435\u043d\u0435\u0440. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u044b \u043f\u0438\u0448\u0438\u0442\u0435 <code>yield $socket-&gt;read()<\/code>.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0443\u0441\u043b\u044b\u0448\u0430\u043b \u043e\u0431 \u044d\u0442\u043e\u043c, \u044f \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a\u0430\u044f \u044d\u0442\u043e \u043a\u0440\u0443\u0442\u0430\u044f \u0432\u0435\u0449\u044c, \u044d\u0442\u043e \u0438 \u043c\u043e\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043b\u043e \u043c\u0435\u043d\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 PHP. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u043d\u0430\u0445\u043e\u0436\u0443 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0443\u0433\u0430\u044e\u0449\u0438\u043c\u0438. \u0415\u0441\u0442\u044c \u0442\u043e\u043d\u043a\u0430\u044f \u0433\u0440\u0430\u043d\u044c \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u0436\u0443\u0442\u043a\u043e\u0439 \u0433\u0440\u044f\u0437\u044c\u044e, \u0438 \u044f \u0434\u0443\u043c\u0430\u044e, \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u0442\u043e\u044f\u0442 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043d\u0438. \u041c\u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u0442\u0430\u043a\u043e\u043c \u043a\u043b\u044e\u0447\u0435, \u0432 \u043a\u0430\u043a\u043e\u043c \u044f \u043e\u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435, \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0432\u044b\u0438\u0433\u0440\u044b\u0448\u043d\u044b\u043c.<\/p>\n<p>  \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u0434\u0443\u043c\u0430\u044e \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0442\u0435\u043c\u0430 \u0438 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u044b \u0442\u043e\u0436\u0435 \ud83d\ude42<\/p>\n<p>  \u041f\u0421 \u043e\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430: \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0438 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438, \u0432 \u0442.\u0447. \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u044b\u0435. \u0435\u0441\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u043b\u0438 \u0442\u0430\u043a\u0443\u044e \u2014 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430.        \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/164173\/\"> http:\/\/habrahabr.ru\/post\/164173\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">       \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u043e\u0432\u043e\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u0432 PHP 5.5 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d (\u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c). \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u043b\u0438 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u044b \u0432 <a href=\"http:\/\/de2.php.net\/manual\/en\/language.generators.overview.php\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a> \u0438 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 <a href=\"http:\/\/blog.ircmaxell.com\/2012\/07\/what-generators-can-do-for-you.html\">\u044d\u0442\u043e\u043c<\/a> \u0438\u043b\u0438 \u0432 <a href=\"http:\/\/sheriframadan.com\/2012\/10\/test-drive-php-5-5-a-sneak-peek\/#generators\">\u044d\u0442\u043e\u043c<\/a>). \u0421\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u042d\u0442\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0439, \u043d\u043e \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0441 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0441\u0442\u0443\u043f\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u043e\u0432. \u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u043d\u0430\u0435\u0442\u0435 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u0442\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0430\u0437\u0434\u0435\u043b\u0443 \u00ab\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u043e\u0441\u0442\u044c\u00bb.<\/p>\n<h4>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b<\/h4>\n<p>  \u0421\u0443\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0430 <em>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/em>, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c. \u0418\u043b\u0438, \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u0430\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0433\u043e \u043a\u043e\u0434\u0430.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-164173","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/164173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=164173"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/164173\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=164173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=164173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=164173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}