在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 網(wǎng)頁設(shè)計教程 > 詳細頁面

php中協(xié)程的詳細介紹(代碼)

php中協(xié)程的詳細介紹(代碼)

更新時間:2025-12-04 文章作者:未知 信息來源:網(wǎng)絡 閱讀次數(shù):

網(wǎng)頁的本質(zhì)就是超級文本標記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強大的網(wǎng)頁。因而,超級文本標記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立...
網(wǎng)頁的本質(zhì)就是超級文本標記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強大的網(wǎng)頁。因而,超級文本標記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立在超文本基礎(chǔ)之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。
本文先介紹了生成器的概念,重點是yield的用法及生成器的接口。協(xié)程部分則簡要說了協(xié)程的原理,以及PHP協(xié)程編程中應當注意的事項。

PHP自5.5起引入了生成器(Generator),基于其可實現(xiàn)協(xié)程編程。本文先回顧生成器,然后過渡到協(xié)程編程。

yield與生成器

生成器

生成器是一種數(shù)據(jù)類型,實現(xiàn)了iterator接口。不能通過new得到生成器實例,也沒有獲取生成器實例的靜態(tài)方法。得到生成器實例的唯一辦法是調(diào)用生成器函數(shù)(包含yield關(guān)鍵字的函數(shù))。調(diào)用生成器函數(shù)直接返回一個生成器對象,生成器運行時函數(shù)內(nèi)的代碼才開始執(zhí)行。

先上代碼直觀感受一下yield與生成器:

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

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

echo 'unreachable code!';

# 執(zhí)行結(jié)果
object(Generator)#1 (0) {
}
exit script when generator runs.

foo函數(shù)包含yield關(guān)鍵字,變身為生成器函數(shù)。調(diào)用foo不會執(zhí)行函數(shù)體中的任何代碼,而是返回一個生成器實例。生成器運行后,foo函數(shù)內(nèi)的代碼執(zhí)行,腳本結(jié)束。

如其名,生成器可以用來生成數(shù)據(jù)。只是其生成數(shù)據(jù)的方式與其他函數(shù)不一樣:生成器通過yield返回數(shù)據(jù),而非return; yield返回數(shù)據(jù)后,生成器函數(shù)不會銷毀,只是暫停運行,未來可以從暫停處恢復運行;生成器運行一次,(只)返回一個數(shù)據(jù),多次運行就返回多個數(shù)據(jù);不調(diào)用生成器獲取數(shù)據(jù),生成器內(nèi)的代碼就躺著不動,所謂動次打次,說的就是生成器生成數(shù)據(jù)的樣子。

生成器實現(xiàn)了迭代器接口,獲取生成器數(shù)據(jù)可以用foreach循環(huán)或手工current/next/valid。如下代碼演示數(shù)據(jù)生成和遍歷:

# generator2.php
function foo() {
  # 返回鍵值對數(shù)據(jù)
  yield "key1" => "value1";
  $count = 0;
  while ($count < 5) {
    # 返回值,key自動生成
    yield $count;
    ++ $count;
  }
  # 不返回值,相當于返回null
  yield;
}

# 手動獲取生成器數(shù)據(jù)
$gen = foo();
while ($gen->valid()) {
  fwrite(STDOUT, "key:{$gen->key()}, value:{$gen->current()}\n");
  $gen->next();
}

# foreach 遍歷數(shù)據(jù)
fwrite(STDOUT, "\ndata from foreach\n");
foreach (foo() as $key => $value) {
    fwrite(STDOUT, "key:$key, value:$value\n");
}

yield

yield關(guān)鍵字是生成器的核心,其讓普通函數(shù)異化(進化)為生成器函數(shù)。yield有“讓出”的意思,程序執(zhí)行到yield語句會暫停執(zhí)行,讓出CPU并將控制權(quán)返回到調(diào)用者,下次執(zhí)行時從中斷點繼續(xù)執(zhí)行。控制權(quán)返回到調(diào)用者時,yield語句可以攜帶值返回給調(diào)用方。generator2.php腳本演示了yield返回值的三種形式:

  1. yield $key => $value: 返回數(shù)據(jù)的key和value;

  2. yield $value: 返回數(shù)據(jù),key由系統(tǒng)分配;

  3. yield: 返回null值,key由系統(tǒng)分配;

yield讓函數(shù)可以隨時暫停、繼續(xù)執(zhí)行,并返回數(shù)據(jù)給調(diào)用方。如果繼續(xù)執(zhí)行時需要外部數(shù)據(jù),這個工作由生成器的send函數(shù)提供:出現(xiàn)在yield左邊等號的變量會接收send傳來的值。看一個常見的send函數(shù)使用樣例:

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

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

send讓生成器之間和外部有雙向數(shù)據(jù)通信的能力:yield返回數(shù)據(jù);send提供繼續(xù)運行的支撐數(shù)據(jù)。由于send讓生成器繼續(xù)執(zhí)行,這個行為與迭代器的next接口類似,next相當于send(null)

其他

  1. $string = yield $data;的表達式在PHP7前不合法,需要加括號:$string = (yield $data);

  2. PHP5生成器函數(shù)不能return值,PHP7后可以return值,并通過生成器的getReturn獲取返回的值。

  3. PHP7新增了yield from語法,實現(xiàn)了生成器委托。

  4. 生成器是單向迭代器,開動后不能調(diào)用rewind

總結(jié)

相對于其他迭代器,生成器具有性能開銷小、編碼容易的特點。其作用主要體現(xiàn)在三個方面:

  1. 數(shù)據(jù)生成(生產(chǎn)者),通過yield返回數(shù)據(jù);

  2. 數(shù)據(jù)消費(消費者),消費send傳來的數(shù)據(jù);

  3. 實現(xiàn)協(xié)程。

關(guān)于PHP中的生成器及基本用法,建議看看 2gua 大佬的博文:PHP之生成器,生動有趣且易懂。

協(xié)程編程

協(xié)程(coroutine)是隨時可中斷、恢復執(zhí)行的子程序,yield關(guān)鍵字讓函數(shù)擁有這種能力,所以可以用于協(xié)程編程。

進程、線程和協(xié)程

線程歸屬于進程,一個進程可有多個線程。進程是計算機分配資源的最小單位,線程是計算機調(diào)度執(zhí)行的最小單位。進程和線程均由操作系統(tǒng)調(diào)度。

協(xié)程可以看成“用戶態(tài)的線程”,需要用戶程序?qū)崿F(xiàn)調(diào)度。線程和進程由操作系統(tǒng)調(diào)度“搶占式”交替運行,協(xié)程主動讓出CPU“協(xié)商式”交替運行。協(xié)程十分的輕量,協(xié)程切換不涉及線程切換,執(zhí)行效率高,數(shù)目越多,越能體現(xiàn)協(xié)程的優(yōu)勢。

生成器和協(xié)程

生成器實現(xiàn)的協(xié)程屬于無棧協(xié)程(stackless coroutine),即生成器函數(shù)只有函數(shù)幀,運行時附加到調(diào)用方的棧上執(zhí)行。不同于功能強大的有棧協(xié)程(stackful coroutine),生成器暫停后無法控制程序走向,只能將控制權(quán)被動的歸還調(diào)用者;生成器只能中斷自身,不能中斷整個協(xié)程。當然,生成器的好處便是效率高(暫停時只需保存程序計數(shù)器即可),實現(xiàn)簡單。

協(xié)程編程

說到PHP中的協(xié)程編程,相信大部分人已經(jīng)看過鳥哥轉(zhuǎn)載(翻譯)的這篇博文:在PHP中使用協(xié)程實現(xiàn)多任務調(diào)度。原文作者 nikic 是PHP的核心開發(fā)者,生成器功能的倡議者和實現(xiàn)人。想深入了解生成器及基于其的協(xié)程編程,nikic關(guān)于生成器的RFC和鳥哥網(wǎng)站上的文章必讀。

先看看基于生成器的協(xié)程工作方式:協(xié)程協(xié)作式工作,即協(xié)程之間通過主動讓出CPU達到多任務交替運行(即并發(fā)多任務,但不是并行);一個生成器可看成一個協(xié)程,執(zhí)行到yield語句,讓出CPU控制權(quán)回到調(diào)用方,調(diào)用方繼續(xù)執(zhí)行其他協(xié)程或其他代碼。

再來看鳥哥博客理解的難點何在。協(xié)程非常輕量,一個系統(tǒng)中可以同時存在成千上萬個協(xié)程(生成器)。而操作系統(tǒng)不會對協(xié)程調(diào)度,安排協(xié)程執(zhí)行的工作就落到開發(fā)者身上。部分人看不懂鳥哥文章的協(xié)程部分,是因為里面說協(xié)程編程少(寫協(xié)程主要就是寫生成器函數(shù)),而是花筆墨實現(xiàn)了一個協(xié)程的調(diào)度器(scheduler或者kernel):模擬了操作系統(tǒng),對所有協(xié)程進行公平調(diào)度。PHP開發(fā)一般的思維是:我寫了這些代碼,PHP引擎會調(diào)用我這些代碼得到預期結(jié)果。而協(xié)程編程不僅要寫干活的代碼,還要寫指導這些代碼什么時候干活的代碼。沒有很好的把握作者的思維,理解起來自然會難一些。需要自行調(diào)度,這是生成器協(xié)程相對于原生協(xié)程(async/await形式)的一個缺點。

知道了協(xié)程是怎么回事,那么它能用來干什么?協(xié)程自行讓出CPU來協(xié)作高效利用CPU,讓出的時機當然應該是程序阻塞時。什么地方會讓程序阻塞呢?用戶態(tài)的代碼鮮有阻塞,阻塞主要是系統(tǒng)調(diào)用。而系統(tǒng)調(diào)用的大頭是IO,所以協(xié)程的主要應用場景在網(wǎng)絡編程。為了讓程序高性能、高并發(fā),程序應該異步執(zhí)行不能阻塞。既然異步執(zhí)行,就需要通知和回調(diào),寫回調(diào)函數(shù)避免不了“回調(diào)地獄(callback hell)”的問題:代碼可讀性差,程序執(zhí)行流程散落在層層回調(diào)函數(shù)中等。解決回調(diào)地獄的方式主要有兩種:Promise和協(xié)程。協(xié)程能以同步的方式編寫代碼,在高性能網(wǎng)絡編程(IO密集型)中是推薦的。

再回過頭看PHP中的協(xié)程編程。PHP中基于生成器實現(xiàn)實現(xiàn)協(xié)程編程,優(yōu)先推薦使用RecoilPHPAmp等協(xié)程框架。這些框架已經(jīng)寫好了調(diào)度器,在其上開發(fā)直接寫生成器函數(shù),內(nèi)核會自動調(diào)度執(zhí)行(想讓一個函數(shù)以協(xié)程方式調(diào)度執(zhí)行,在函數(shù)體內(nèi)加上yield即可)。如果不想用yield方式進行協(xié)程編程,推薦swoole或其衍生框架,能做到類似golang的協(xié)程編程體驗,又能享受PHP的開發(fā)效率。

如果想用原生態(tài)的做PHP協(xié)程編程,類似鳥哥博客中的調(diào)度器必不可少。調(diào)度器調(diào)度協(xié)程執(zhí)行,協(xié)程中斷后控制權(quán)又回到調(diào)度器中。所以調(diào)度器應該總是在主(事件)循環(huán)中,即CPU不在執(zhí)行協(xié)程,就應當在執(zhí)行調(diào)度器的代碼。無協(xié)程運行時,調(diào)度器應當自我阻塞避免消耗CPU(鳥哥博客中使用了內(nèi)置的select系統(tǒng)調(diào)用),等待事件到來再執(zhí)行相應的協(xié)程。程序運行期間,除了調(diào)度器阻塞,協(xié)程在運行過程中不應該調(diào)用阻塞API。

總結(jié)

在協(xié)程編程中,yield的主要作用是將控制權(quán)轉(zhuǎn)讓,無需糾結(jié)于其返回值(基本上yield返回的值會在下次執(zhí)行時直接send過來)。重點應當關(guān)注控制權(quán)轉(zhuǎn)讓的時機,以及協(xié)程的運作方式。

另外需要說明一點,協(xié)程和異步?jīng)]有多大關(guān)系,還要看運行環(huán)境支撐。常規(guī)的PHP運行環(huán)境,即使用了promise/coroutine,也還是同步阻塞的。再牛逼的協(xié)程框架,sleep一下也不好使了。作為類比,即使JavaScript不使用promise/async這些技術(shù),也是異步非阻塞的。

通過生成器和Promise,能實現(xiàn)類似于await的協(xié)程編程,相關(guān)代碼在Github上很多,本文不再給出。

相關(guān)推薦:

PHP 中$_SERVER 詳細介紹

PHP中的output_buffering詳細介紹,outputbuffering_PHP教程

以上就是php中協(xié)程的詳細介紹(代碼)的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!


網(wǎng)站建設(shè)是一個廣義的術(shù)語,涵蓋了許多不同的技能和學科中所使用的生產(chǎn)和維護的網(wǎng)站。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 日韩成人三级视频| 欧洲精品在线播放| 亚洲黄色片免费| 国产不卡的av| 精品免费久久久久久久| 国产精品久久中文字幕| 欧美激情成人网| 91丨九色丨蝌蚪| 免费在线看黄色片| 无码精品国产一区二区三区免费| 中文字幕国产传媒| 婷婷视频在线播放| 啊啊啊一区二区| 亚洲免费黄色录像| 你懂的av在线| 手机av在线免费| 国产精品自拍片| 粉色视频免费看| av网站大全免费| 污视频免费在线观看网站| 男人天堂网站在线| 人妻内射一区二区在线视频 | 亚洲国产日韩欧美在线观看| 日本一本在线视频| 蜜臀av午夜一区二区三区| 8x8x成人免费视频| 97av视频在线观看| а 天堂 在线| 日日碰狠狠躁久久躁婷婷| 三上悠亚免费在线观看| 日韩视频在线免费看| 青青草综合视频| 成人综合久久网| 国产91在线视频观看| 日本丰满大乳奶| 人人干人人干人人| 少妇性饥渴无码a区免费| 国产免费内射又粗又爽密桃视频| 日本一本二本在线观看| 黄色激情在线视频| 好色先生视频污| 久久久久久综合网| 一区二区在线播放视频| 国产精品裸体瑜伽视频| 色乱码一区二区三区熟女| 成年人三级黄色片| 黄色手机在线视频| 男女视频一区二区三区| 国产91xxx| 99久热在线精品视频| 免费观看国产视频在线| 日韩av福利在线观看| 中文字幕第17页| 午夜国产一区二区三区| 亚洲男人天堂色| 国产v亚洲v天堂无码久久久| 久草青青在线观看| 北条麻妃在线观看| 成人在线观看黄| 国模吧无码一区二区三区| 大陆极品少妇内射aaaaa| 99在线精品免费视频| 亚洲一区二区三区av无码| av在线com| 国内精品视频一区二区三区| 久久av高潮av| 国产精品又粗又长| 久久美女福利视频| 成人性生生活性生交12| 国产三级国产精品国产专区50| 无码少妇一区二区三区芒果| 91小视频网站| 免费在线精品视频| 18禁网站免费无遮挡无码中文| 黄页网站大全在线观看| 欧美牲交a欧美牲交aⅴ免费真| 日本a√在线观看| 毛片毛片毛片毛片毛| 成人一级生活片| 国产三级三级三级看三级| 99热一区二区| 青青草综合在线| 日韩欧美在线免费观看视频| 成人性生交免费看| 久久福利一区二区| 国产v亚洲v天堂无码久久久 | 日本精品福利视频| av7777777| 91丨九色丨蝌蚪| 日韩av高清在线看片| 黑森林精品导航| 九一免费在线观看| 国产免费黄色av| 三级av免费看| 日本www在线播放| 在线无限看免费粉色视频| 精品欧美一区免费观看α√| www.精品在线| 久久精品视频16| 欧美日韩理论片| 一本色道无码道dvd在线观看| 91蝌蚪视频在线| 国产情侣av自拍| 欧洲精品在线播放| 久久精品亚洲天堂| 97在线播放视频| 成年人视频网站免费| 可以看污的网站| 欧美在线观看视频网站| 国产精品久久久久久久久电影网| av污在线观看| 午夜精品久久久久久久无码| 免费观看中文字幕| 在线观看免费的av| 欧美精品成人网| 国产 福利 在线| 久久久久99精品成人片| 最新黄色av网站| 欧美激情第一区| 在线观看免费黄网站| 日本一区二区黄色| 九一国产精品视频| www.男人天堂网| 337p亚洲精品色噜噜狠狠p| 国产又粗又长又爽又黄的视频| 亚洲中文字幕久久精品无码喷水| 国产免费一区二区视频| 久久久久久久香蕉| 永久免费看av| 日本一道在线观看| 国产精品自拍合集| 欧美狂野激情性xxxx在线观| 黄色免费高清视频| 精品一区二区成人免费视频| 亚洲天堂一区二区在线观看| 91 视频免费观看| 午夜激情视频网| 蜜臀在线免费观看| 91网站在线观看免费| 超级碰在线观看| 97中文字幕在线| 成人毛片视频网站| 看av免费毛片手机播放 | 蜜臀av午夜一区二区三区| 欧美精品一区免费| 欧美激情精品久久久久久小说| 欧美一区二区三区爽大粗免费| 青青草视频在线免费播放| 欧美亚洲日本一区二区三区| 狠狠97人人婷婷五月| 任你操这里只有精品| 91制片厂毛片| 手机在线免费毛片| 国产美女永久无遮挡| 久久成人免费观看| 手机看片福利日韩| 亚洲第一天堂久久| youjizz.com在线观看| 精品少妇人妻av免费久久洗澡| 99re在线视频免费观看| 亚欧激情乱码久久久久久久久| 亚洲国产欧美91| 三上悠亚久久精品| 欧美日韩在线观看不卡| 亚洲综合激情五月| 日日鲁鲁鲁夜夜爽爽狠狠视频97 | 大桥未久一区二区| 91成人在线观看喷潮教学| 成年人在线观看视频免费| 91九色国产ts另类人妖| 久久久亚洲精品无码| 中文字幕成人免费视频| 青草视频在线观看视频| 孩娇小videos精品| av片在线免费| 国产乱女淫av麻豆国产| 免费高清一区二区三区| jizz欧美性11| 天堂…中文在线最新版在线| 日本高清久久久| 六月丁香激情网| 永久av免费在线观看| 成人黄色片视频| 4444亚洲人成无码网在线观看| 日韩一级在线免费观看| 亚洲啊啊啊啊啊| 99热一区二区| 蜜臀av午夜一区二区三区| 欧美 亚洲 视频| www.亚洲自拍| 日韩中文字幕二区| 大荫蒂性生交片| 最新av在线免费观看| 亚洲不卡视频在线| 男人靠女人免费视频网站| 成人在线国产视频| 大片在线观看网站免费收看| 亚洲一级片网站| 国内自拍视频网| 91看片就是不一样|