成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP協(xié)程

SolomonXie / 2669人閱讀

摘要:協(xié)程協(xié)程就是用戶態(tài)的線程要理解是什么是用戶態(tài)的線程,必然就要先理解什么是內(nèi)核態(tài)的線程。記住,不是協(xié)程,而是協(xié)程需要借助的特性來(lái)實(shí)現(xiàn)。

協(xié)程
“協(xié)程”就是用戶態(tài)的線程

要理解是什么是“用戶態(tài)的線程”,必然就要先理解什么是“內(nèi)核態(tài)的線程”。 內(nèi)核態(tài)的線程是由操作系統(tǒng)來(lái)進(jìn)行調(diào)度的,在切換線程上下文時(shí),要先保存上一個(gè)線程的上下文,然后執(zhí)行下一個(gè)線程,當(dāng)條件滿足時(shí),切換回上一個(gè)線程,并恢復(fù)上下文。 協(xié)程也是如此,只不過(guò),用戶態(tài)的線程不是由操作系統(tǒng)來(lái)調(diào)度的,而是由程序員來(lái)調(diào)度的,是在用戶態(tài)的 -- 摘自鏈接描述

關(guān)于“用戶態(tài)線程”,我們用個(gè)小例子來(lái)加深理解

我們有兩個(gè)函數(shù) task1,task2,我們來(lái)手動(dòng)調(diào)度它們的執(zhí)行順序,比如在task1執(zhí)行一半的時(shí)候去執(zhí)行task2,兩個(gè)或者多個(gè)函數(shù)之間交替執(zhí)行(這就是協(xié)程的概念)。

我們來(lái)個(gè)正常的函數(shù)調(diào)用方式:


可想而知,以上的輸出肯定是:

task1函數(shù) 執(zhí)行第1
task1函數(shù) 執(zhí)行第2
task2函數(shù) 執(zhí)行第1
task2函數(shù) 執(zhí)行第2

但是我想在程序輸出task1函數(shù) 執(zhí)行1之后就輸出task2函數(shù) 執(zhí)行1怎么辦?

這個(gè)時(shí)候 yield 就派上用場(chǎng)了,PHP里的協(xié)程是需要借助 yield 來(lái)完成的。記住,yield 不是協(xié)程,而是協(xié)程需要借助 yield 的特性來(lái)實(shí)現(xiàn)。

current();
$task2->current();

以上輸出:

task1函數(shù) 執(zhí)行1
task2函數(shù) 執(zhí)行1

很好,以上結(jié)果達(dá)到了我們的預(yù)期。但是怎么讓函數(shù)里的代碼往下執(zhí)行呢?

調(diào)用生成器的next方法:

$task1->next();
$task2->next();

最后你將看到的輸出結(jié)果是兩個(gè)函數(shù)交替執(zhí)行輸出的:

task1函數(shù) 執(zhí)行1
task2函數(shù) 執(zhí)行1
task1函數(shù) 執(zhí)行2
task2函數(shù) 執(zhí)行2
小段總結(jié)

以上的代碼實(shí)現(xiàn)可以抽象出兩個(gè)概念,任務(wù)調(diào)度,任務(wù)就是task函數(shù),調(diào)度就是我們?cè)趺慈フ{(diào)用這些task函數(shù)

調(diào)度器和任務(wù)生成器

上一個(gè)小段總結(jié)里有兩個(gè)概念叫任務(wù)調(diào)度,我們簡(jiǎn)單的封裝個(gè)任務(wù)生成器和調(diào)度器

// 任務(wù)生成器
$createTask = (function () {
    $tasks = [];
    return function ($callback) use (&$tasks) {
        $task = [
            "task" => $callback(),
            "id" => count($tasks) + 1,
        ];
        array_push($tasks, $task);
        return $task;
    };
})();

// 調(diào)度器
function schedule($tasks)
{
    $first = [];
    while (!empty($tasks)) {
        $task = array_shift($tasks);
        if (!array_key_exists($task["id"], $first)) {
            $first[$task["id"]] = true;
            $task["task"]->current();
        } else {
            $task["task"]->next();
        }
        if (!$task["task"]->valid()) {
            unset($tasks[$k]);
        } else {
            array_push($tasks, $task);
        }
    }
}

使用

$tasks = [
    $createTask(function () {
        echo "任務(wù)1 執(zhí)行第1次
";
        yield;
        echo "任務(wù)1 執(zhí)行第2次
";
    }),
    $createTask(function () {
        echo "任務(wù)2 執(zhí)行第1次
";
        yield;
        echo "任務(wù)2 執(zhí)行第2次
";
    })
];

schedule($tasks);

輸出結(jié)果:

任務(wù)1 執(zhí)行第1次
任務(wù)2 執(zhí)行第1次
任務(wù)1 執(zhí)行第2次
任務(wù)2 執(zhí)行第2次

可以從結(jié)果看出,調(diào)度器已經(jīng)實(shí)現(xiàn)了多個(gè)任務(wù)之間進(jìn)行協(xié)作。

網(wǎng)絡(luò)請(qǐng)求
現(xiàn)在有個(gè)需求!就是任務(wù)在遇到網(wǎng)絡(luò)請(qǐng)求的時(shí)候,我們無(wú)需等待網(wǎng)絡(luò)請(qǐng)求的響應(yīng)結(jié)果,而是遇到網(wǎng)絡(luò)請(qǐng)求的時(shí)候,把這個(gè)任務(wù)掛起,然后去執(zhí)行其它任務(wù),等網(wǎng)絡(luò)請(qǐng)求收到響應(yīng)結(jié)果了再通知我們處理

這時(shí)候需要我們用到非阻塞IO調(diào)用相關(guān)技術(shù),涉及到系統(tǒng)內(nèi)核層面,想了解可以點(diǎn)擊鏈接描述

在PHP里我們需要安裝個(gè)擴(kuò)展eio,大家自行安裝

pecl install eio

編碼:

$tasks = [
    $createTask(function () {
        echo "任務(wù)1 執(zhí)行第1次
";
        yield;
        echo "任務(wù)1 執(zhí)行第2次
";
    }),
    $createTask(function () {
        echo "任務(wù)2 執(zhí)行第1次
";

        eio_custom(function () {
            return file_get_contents("https://segmentfault.com/");
        }, EIO_PRI_DEFAULT, function ($data, $ret) {
            echo "請(qǐng)求完成
";
        });
        
        yield;

        echo "任務(wù)2 執(zhí)行第2次
";
    })
];

schedule($tasks);

eio_event_loop();

任務(wù)2 執(zhí)行第1次的時(shí)候,遇到網(wǎng)絡(luò)請(qǐng)求,我們把請(qǐng)求任務(wù)交給系統(tǒng)內(nèi)核,然后切換到其它任務(wù)去,等請(qǐng)求任務(wù)完成后回調(diào)我們傳入的函數(shù)。

輸出結(jié)果:

任務(wù)1 執(zhí)行第1次
任務(wù)2 執(zhí)行第1次
任務(wù)1 執(zhí)行第2次
任務(wù)2 執(zhí)行第2次
任務(wù)2 執(zhí)行第1次的請(qǐng)求完成

完!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29283.html

相關(guān)文章

  • PHP回顧之協(xié)程

    摘要:本文先回顧生成器,然后過(guò)渡到協(xié)程編程。其作用主要體現(xiàn)在三個(gè)方面數(shù)據(jù)生成生產(chǎn)者,通過(guò)返回?cái)?shù)據(jù)數(shù)據(jù)消費(fèi)消費(fèi)者,消費(fèi)傳來(lái)的數(shù)據(jù)實(shí)現(xiàn)協(xié)程。解決回調(diào)地獄的方式主要有兩種和協(xié)程。重點(diǎn)應(yīng)當(dāng)關(guān)注控制權(quán)轉(zhuǎn)讓的時(shí)機(jī),以及協(xié)程的運(yùn)作方式。 轉(zhuǎn)載請(qǐng)注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請(qǐng)求 cookie web響應(yīng) sess...

    Java3y 評(píng)論0 收藏0
  • PHP 協(xié)程:Go + Chan + Defer

    摘要:為語(yǔ)言提供了強(qiáng)大的協(xié)程編程模式。提供的協(xié)程語(yǔ)法借鑒自,在此向開(kāi)發(fā)組致敬協(xié)程可以與很好地互補(bǔ)。并發(fā)執(zhí)行使用創(chuàng)建協(xié)程,可以讓和兩個(gè)函數(shù)變成并發(fā)執(zhí)行。協(xié)程需要拿到請(qǐng)求的結(jié)果。 Swoole4為PHP語(yǔ)言提供了強(qiáng)大的CSP協(xié)程編程模式。底層提供了3個(gè)關(guān)鍵詞,可以方便地實(shí)現(xiàn)各類功能。 Swoole4提供的PHP協(xié)程語(yǔ)法借鑒自Golang,在此向GO開(kāi)發(fā)組致敬 PHP+Swoole協(xié)程可以與...

    nidaye 評(píng)論0 收藏0
  • Swoole協(xié)程之旅-前篇

    摘要:協(xié)程完全有用戶態(tài)程序控制,所以也被成為用戶態(tài)的線程。目前支持協(xié)程的語(yǔ)言有很多,例如等。協(xié)程之旅前篇結(jié)束,下一篇文章我們將深入分析原生協(xié)程部分的實(shí)現(xiàn)。 寫(xiě)在最前 ??Swoole協(xié)程經(jīng)歷了幾個(gè)里程碑,我們需要在前進(jìn)的道路上不斷總結(jié)與回顧自己的發(fā)展歷程,正所謂溫故而知新,本系列文章將分為協(xié)程之旅前、中、后三篇。 前篇主要介紹協(xié)程的概念和Swoole幾個(gè)版本協(xié)程實(shí)現(xiàn)的主要方案技術(shù); 中篇主...

    terasum 評(píng)論0 收藏0
  • Swoole 4.4 協(xié)程搶占式調(diào)度器詳解

    摘要:搶占式調(diào)度我們?cè)诮衲昴瓿蹙陀?jì)劃實(shí)現(xiàn)的搶占式調(diào)度,以滿足實(shí)現(xiàn)有些場(chǎng)景下的不均衡調(diào)度帶來(lái)的問(wèn)題??紤]開(kāi)線程,負(fù)責(zé)檢查當(dāng)前執(zhí)行協(xié)程執(zhí)行時(shí)間。達(dá)到我們的第二個(gè)協(xié)程主動(dòng)搶占第一個(gè)協(xié)程的效果。 前言 Swoole內(nèi)核團(tuán)隊(duì)開(kāi)設(shè)的專欄,會(huì)逐漸投入精力寫(xiě)文章介紹Swoole的開(kāi)發(fā)歷程,實(shí)現(xiàn)原理,應(yīng)用實(shí)踐等,大家可以更好的交流,共同學(xué)習(xí),建設(shè)PHP生態(tài)。 協(xié)程調(diào)度 去年Swoole推出了4.0版本后,完整...

    Bowman_han 評(píng)論0 收藏0
  • PHP下的異步嘗試二:初識(shí)協(xié)程

    摘要:如果僅依靠程序自動(dòng)交出控制的話,那么一些惡意程序?qū)?huì)很容易占用全部時(shí)間而不與其他任務(wù)共享。多個(gè)操作可以在重疊的時(shí)間段內(nèi)進(jìn)行。 PHP下的異步嘗試系列 如果你還不太了解PHP下的生成器,你可以根據(jù)下面目錄翻閱 PHP下的異步嘗試一:初識(shí)生成器 PHP下的異步嘗試二:初識(shí)協(xié)程 PHP下的異步嘗試三:協(xié)程的PHP版thunkify自動(dòng)執(zhí)行器 PHP下的異步嘗試四:PHP版的Promise ...

    MudOnTire 評(píng)論0 收藏0
  • 關(guān)于PHP協(xié)程與阻塞的思考

    摘要:線程擁有自己獨(dú)立的棧和共享的堆,共享堆,不共享?xiàng)#€程亦由操作系統(tǒng)調(diào)度標(biāo)準(zhǔn)線程是的。以及鳥(niǎo)哥翻譯的這篇詳細(xì)文檔我就以他實(shí)現(xiàn)的協(xié)程多任務(wù)調(diào)度為基礎(chǔ)做一下例子說(shuō)明并說(shuō)一下關(guān)于我在阻塞方面所做的一些思考。 進(jìn)程、線程、協(xié)程 關(guān)于進(jìn)程、線程、協(xié)程,有非常詳細(xì)和豐富的博客或者學(xué)習(xí)資源,我不在此做贅述,我大致在此介紹一下這幾個(gè)東西。 進(jìn)程擁有自己獨(dú)立的堆和棧,既不共享堆,亦不共享?xiàng)?,進(jìn)程由操作系...

    FullStackDeveloper 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<