摘要:訪問安全問題為什么說有訪問安全問題呢傳統(tǒng)地,在的的環(huán)境中,很少有遇到所謂變量安全訪問問題。上下文管理器為了解決這個(gè)問題,我們引入?yún)f(xié)程上下文管理這樣的概念,由此來實(shí)現(xiàn)每個(gè)協(xié)程環(huán)境內(nèi)的數(shù)據(jù)隔離。
訪問安全問題
為什么說有訪問安全問題呢?傳統(tǒng)地,在php的的環(huán)境中,很少有Phper遇到所謂變量安全訪問問題。舉個(gè)例子,代碼大約如下:
class db { protected static $instance; protected $dbCon; function __construct() { /* * 我們這里用stdclass來模擬一個(gè)數(shù)據(jù)庫連接 */ $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);
這個(gè)是在fpm模式下,很常見的數(shù)據(jù)庫連接單例模式的使用。乍一看沒有問題,但實(shí)際上,在協(xié)程環(huán)境下,會(huì)出現(xiàn)連接跨協(xié)程使用問題,舉例如下
go(function (){ go(function (){ db::getInstance()->dbCon()->key = "one"; //假設(shè)這sql執(zhí)行了1s co::sleep(1); var_dump(db::getInstance()->dbCon()->key); }); go(function (){ db::getInstance()->dbCon()->key = "two"; //假設(shè)這sql執(zhí)行了0.1s co::sleep(0.1); var_dump(db::getInstance()->dbCon()->key); }); });
我們會(huì)發(fā)現(xiàn),以上代碼當(dāng)中,協(xié)程2的數(shù)據(jù)污染到了協(xié)程1的數(shù)據(jù),那么因此這樣肯定是不行的。
上下文管理器為了解決這個(gè)問題,我們引入?yún)f(xié)程上下文管理這樣的概念,由此來實(shí)現(xiàn)每個(gè)協(xié)程環(huán)境內(nèi)的數(shù)據(jù)隔離。
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"; //假設(shè)這sql執(zhí)行了1s co::sleep(1); var_dump(dbContext::getInstance()->dbCon()->key); }); go(function (){ dbContext::getInstance()->dbCon()->key = "two"; //假設(shè)這sql執(zhí)行了0.1s co::sleep(0.1); var_dump(dbContext::getInstance()->dbCon()->key); }); });
以上代碼中,我們用每個(gè)協(xié)程的id,來作為每個(gè)協(xié)程棧的數(shù)據(jù)token,用了defer方法,實(shí)現(xiàn)了每個(gè)協(xié)程退出的時(shí)候的數(shù)據(jù)自動(dòng)清理,從而避免了內(nèi)存泄露。
通用版本的連接池與協(xié)程上下文管理我們不難發(fā)現(xiàn),以上代碼中,實(shí)際上依舊是短連接的管理方式,沒辦法對(duì)鏈接進(jìn)行復(fù)用,由于本文章僅做基礎(chǔ)原理講解之用,具體有興趣的同學(xué),可以查看下Easyswoole這個(gè)框架的連接池和協(xié)程上下文管理器,項(xiàng)目主頁在 www.easyswoole.com ,若覺得喜歡,有幫助,可以給easyswoole的github倉庫點(diǎn)個(gè)贊。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31790.html
摘要:然而盡管如此,很多人可能都沒有思考過,如何優(yōu)雅的寫出自己的物聯(lián)網(wǎng)服務(wù)器。 PHP不適合做物聯(lián)網(wǎng)服務(wù)端嗎? 在傳統(tǒng)的思維中,經(jīng)常會(huì)有人告訴你,php不適合用來做物聯(lián)網(wǎng)服務(wù)端,讓你換java,node,go等其他語言,是的,沒錯(cuò)傳統(tǒng)意義上的php,確實(shí)很難做物聯(lián)網(wǎng)服務(wù)器,因?yàn)樗鼘?shí)在太蹩腳了,當(dāng)然,這也不是意味著徹底就不能做。舉個(gè)例子,當(dāng)你想實(shí)現(xiàn)一個(gè)TCP服務(wù)器的時(shí)候,你可能需要寫出原理大約...
摘要:有研究過框架的同學(xué)就會(huì)發(fā)現(xiàn),其實(shí)最核心的,就是用了拓展加上拓展來實(shí)現(xiàn)其底層的網(wǎng)絡(luò)服務(wù)和多進(jìn)程調(diào)度。我們?cè)谀J较拢瑴y(cè)試起五個(gè)進(jìn)程主進(jìn)程要等待回收我們,這樣就很簡單的實(shí)現(xiàn)了一個(gè)多進(jìn)程的協(xié)程服務(wù)。 有研究過Workman框架的同學(xué)就會(huì)發(fā)現(xiàn),其實(shí)workman最核心的,就是用了php socket拓展加上pcntl拓展來實(shí)現(xiàn)其底層的網(wǎng)絡(luò)服務(wù)和多進(jìn)程調(diào)度。那我們今天就來探討如何使用Swoole的...
摘要:本文先回顧生成器,然后過渡到協(xié)程編程。其作用主要體現(xiàn)在三個(gè)方面數(shù)據(jù)生成生產(chǎn)者,通過返回?cái)?shù)據(jù)數(shù)據(jù)消費(fèi)消費(fèi)者,消費(fè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...
摘要:進(jìn)程線程與協(xié)程它們都是并行機(jī)制的解決方案。選擇是任意性的,并在對(duì)實(shí)現(xiàn)做出決定時(shí)發(fā)生。線程池的大小一旦達(dá)到最大值就會(huì)保持不變,如果某個(gè)線程因?yàn)閳?zhí)行異常而結(jié)束,那么線程池會(huì)補(bǔ)充一個(gè)新線程。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。 并發(fā)與并行的概念 并發(fā)(Concurrency): 問題域中的概念—— 程序需要被設(shè)計(jì)成能夠處理多個(gè)同時(shí)(或者幾乎同時(shí))發(fā)生的事件 并行(Parallel...
摘要:上一篇文章第二章實(shí)戰(zhàn)演練開發(fā)網(wǎng)站第五節(jié)輸出相應(yīng)函數(shù)下一篇文章第二章實(shí)戰(zhàn)演練開發(fā)網(wǎng)站第七節(jié)安全機(jī)制有兩種方式可改變同步的處理流程異步化針對(duì)的處理函數(shù)使用修飾器,將默認(rèn)的同步機(jī)制改為異步機(jī)制。使用異步對(duì)象處理耗時(shí)操作,比如本例的。 上一篇文章:Python:Tornado 第二章:實(shí)戰(zhàn)演練:開發(fā)Tornado網(wǎng)站:第五節(jié):RequestHandler:輸出相應(yīng)函數(shù)下一篇文章:Python:...
閱讀 2812·2021-11-24 09:39
閱讀 3381·2021-11-19 09:40
閱讀 2253·2021-11-17 09:33
閱讀 3744·2021-10-08 10:04
閱讀 3035·2021-09-26 09:55
閱讀 1656·2021-09-22 15:26
閱讀 919·2021-09-10 10:51
閱讀 3116·2019-08-30 15:44