摘要:訪問安全問題為什么說有訪問安全問題呢傳統地,在的的環境中,很少有遇到所謂變量安全訪問問題。上下文管理器為了解決這個問題,我們引入協程上下文管理這樣的概念,由此來實現每個協程環境內的數據隔離。
訪問安全問題
為什么說有訪問安全問題呢?傳統地,在php的的環境中,很少有Phper遇到所謂變量安全訪問問題。舉個例子,代碼大約如下:
class db { protected static $instance; protected $dbCon; function __construct() { /* * 我們這里用stdclass來模擬一個數據庫連接 */ $this->dbCon = new stdClass(); } public static function getInstance() { if(!isset(self::$instance)){ self::$instance = new db(); } return self::$instance; } function dbCon() { return $this->dbCon; } } $con = db::getInstance()->dbCon(); $con->key = "new"; var_dump($con->key);
這個是在fpm模式下,很常見的數據庫連接單例模式的使用。乍一看沒有問題,但實際上,在協程環境下,會出現連接跨協程使用問題,舉例如下
go(function (){ go(function (){ db::getInstance()->dbCon()->key = "one"; //假設這sql執行了1s co::sleep(1); var_dump(db::getInstance()->dbCon()->key); }); go(function (){ db::getInstance()->dbCon()->key = "two"; //假設這sql執行了0.1s co::sleep(0.1); var_dump(db::getInstance()->dbCon()->key); }); });
我們會發現,以上代碼當中,協程2的數據污染到了協程1的數據,那么因此這樣肯定是不行的。
上下文管理器為了解決這個問題,我們引入協程上下文管理這樣的概念,由此來實現每個協程環境內的數據隔離。
class dbContext { private $container = []; private static $instance; public static function getInstance() { if(!isset(self::$instance)){ self::$instance = new dbContext(); } return self::$instance; } function dbCon() { $cid = co::getCid(); if(!isset($this->container[$cid])){ $this->container[$cid] = new stdClass(); defer(function (){ $this->destroy(); }); } return $this->container[$cid]; } function destroy() { $cid = co::getCid(); if(!isset($this->container[$cid])){ unset($this->container[$cid]); } } } go(function (){ go(function (){ dbContext::getInstance()->dbCon()->key = "one"; //假設這sql執行了1s co::sleep(1); var_dump(dbContext::getInstance()->dbCon()->key); }); go(function (){ dbContext::getInstance()->dbCon()->key = "two"; //假設這sql執行了0.1s co::sleep(0.1); var_dump(dbContext::getInstance()->dbCon()->key); }); });
以上代碼中,我們用每個協程的id,來作為每個協程棧的數據token,用了defer方法,實現了每個協程退出的時候的數據自動清理,從而避免了內存泄露。
通用版本的連接池與協程上下文管理我們不難發現,以上代碼中,實際上依舊是短連接的管理方式,沒辦法對鏈接進行復用,由于本文章僅做基礎原理講解之用,具體有興趣的同學,可以查看下Easyswoole這個框架的連接池和協程上下文管理器,項目主頁在 www.easyswoole.com ,若覺得喜歡,有幫助,可以給easyswoole的github倉庫點個贊。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/31790.html
摘要:然而盡管如此,很多人可能都沒有思考過,如何優雅的寫出自己的物聯網服務器。 PHP不適合做物聯網服務端嗎? 在傳統的思維中,經常會有人告訴你,php不適合用來做物聯網服務端,讓你換java,node,go等其他語言,是的,沒錯傳統意義上的php,確實很難做物聯網服務器,因為它實在太蹩腳了,當然,這也不是意味著徹底就不能做。舉個例子,當你想實現一個TCP服務器的時候,你可能需要寫出原理大約...
摘要:有研究過框架的同學就會發現,其實最核心的,就是用了拓展加上拓展來實現其底層的網絡服務和多進程調度。我們在模式下,測試起五個進程主進程要等待回收我們,這樣就很簡單的實現了一個多進程的協程服務。 有研究過Workman框架的同學就會發現,其實workman最核心的,就是用了php socket拓展加上pcntl拓展來實現其底層的網絡服務和多進程調度。那我們今天就來探討如何使用Swoole的...
摘要:進程線程與協程它們都是并行機制的解決方案。選擇是任意性的,并在對實現做出決定時發生。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。此線程池支持定時以及周期性執行任務的需求。 并發與并行的概念 并發(Concurrency): 問題域中的概念—— 程序需要被設計成能夠處理多個同時(或者幾乎同時)發生的事件 并行(Parallel...
摘要:上一篇文章第二章實戰演練開發網站第五節輸出相應函數下一篇文章第二章實戰演練開發網站第七節安全機制有兩種方式可改變同步的處理流程異步化針對的處理函數使用修飾器,將默認的同步機制改為異步機制。使用異步對象處理耗時操作,比如本例的。 上一篇文章:Python:Tornado 第二章:實戰演練:開發Tornado網站:第五節:RequestHandler:輸出相應函數下一篇文章:Python:...
閱讀 2824·2021-11-24 09:39
閱讀 3395·2021-11-19 09:40
閱讀 2264·2021-11-17 09:33
閱讀 3754·2021-10-08 10:04
閱讀 3045·2021-09-26 09:55
閱讀 1669·2021-09-22 15:26
閱讀 932·2021-09-10 10:51
閱讀 3131·2019-08-30 15:44