關於PHP中協程和阻塞的一些理解與思考

2022-09-28 19:54:24 字數 1964 閱讀 1138

前言

程序、執行緒、協程

關於程序、執行緒、協程,有非常詳細和豐富的部落格或者學習資源,我不在此做贅述,我大致在此介紹一下這幾個東西。

php中的協程實現基礎 yield

yield的根本實現是生成器類,而迭代器類是迭代器介面的實現:

generator implements iterator

以上解www.cppcns.com析可以參考php官方文件。

以及這篇詳細文件:

我就以他實現的協程多任務排程為基礎做一下例子說明並說一下關於我在阻塞方面所做的一些思考。

自定義簡單定時執行任務示例:

(此例子必須依賴於以上鳥哥實現的協程排程**)

class timer

public function run()

} /**

* 定時執行檢查

*/ public function valid() else

} public function setend($isend)

public function getend()

}/**

* 模擬阻塞的協程1

* */

function taskobject1()

echo '

'.'a '.$value;

});$tid = (yield gettaskid());

while (true)

yield $timer->run(); }}

/** * 模擬阻塞的協程2

* */

function taskobject2()

echo '

'.'b '.$value;

});$tid = (yield gettaskid());

while (true)

yield $timer->run(); }}

$scheduler = new scheduler;

$scheduler->newtask(taskobject1());

$scheduler->newtask(taskobject2());

$scheduler->run();

以上實現的是:

思考:我為什麼要做以上這件事情呢?因為我發現協程實現雖然很強大也很有意思,能讓多工並行,但是我在其中乙個任務裡呼叫系統函式sleep()的時候,阻塞任務會阻止協程切換,其實從協程的實現原理上來書也是這麼回事。

那麼,我也就想模擬協程阻塞,但是不產生阻塞看是否可行。php本身只提供了生成器為協程呼叫提供了支撐,如果不依賴擴充套件,沒有提供多執行緒的程式實現方式,沒有j**a那麼強大,可以開子執行緒進行實現。

我印象中j**a的子執行緒是wnfwjdyf獨立執行且不會相互阻塞的,所以我在想,php既然可以實現類似於多執行緒這樣的機制,那麼能不能實現呼叫過程中非阻塞呢?

經過這樣乙個實現和思考,一開始是陷入了乙個誤區的,是由於php原生函式sleep() 程式設計客棧阻塞造成的思維誤區,那就是認為要想真正實現非阻塞或者說實現非同步的話,是必須依賴於語言底層的。

後來,我想明白了乙個道理,既然某個方法或者函式在執行過程中,會產生阻塞,那麼把當前這個方法換成自定義的,做成非阻塞(相對於整個協程排程來說)不就行了嗎?比如上面的定時執行我自己實現了乙個。

而另一方面,協程排程本身的目的也是為了把任務執行過程切成盡量小片,從而快速切換執行,達到並行的目的。從這方面來看,協程應該也算是一種程式設計思想。

以下是乙個程式切成盡量小片執行的例子:

// 乙個簡單的例子

<?php function xrange($start, $end, $step = 1) }

foreach (xrange(1, 1000000) as $num)

這個例子是把原本用 range 生成乙個很大的整型陣列的方式切換為分片執行,也就是說在遍歷的時候再去取到指定的值,從**上來看,記憶體消耗相對於之前來說就非常小了。

總結本文標題: 關於php中協程和阻塞的一些理解與思考

本文位址:

關於協程中yield return的一些使用

1.協程與執行緒 unity中的特殊在於所有的指令碼和 都是在乙個主線程裡執行的,協程也不例外。協程與執行緒的相似點只在於,協程看起來也可以與其他函式並行執行。但本質上來說,執行緒 是通過可以開啟多個子執行緒同時執行程式,而達到並行。而協程則是通過每幀檢測的方式,在自己與其他函式之間切換。2.yie...

關於java中Exception的一些理解

在方法的宣告時使用,作用是宣告該方法可能有該種異常,不一定會有,是一種傾向,一種預防措施,保證 的健壯性。讓你的呼叫者知道,我這個方法可能會丟擲何種異常,讓我的呼叫者知道並且要做出一定的處理。因此就要求其呼叫者做出一定 防範措施 來進行捕獲可能會丟擲的異常並解決或者進行繼續丟擲 不推薦 例如進行tr...

關於Cookie和session的一些理解

1.domain表示的是cookie所在的域,預設為請求的位址,如 為www.test.com test test.aspx,那麼 domain預設為www.test.com。而跨域訪問,如域a為t1.test.com,域b為t2.test.com,那麼在域a生產乙個令域a和 域b都能訪問的cook...