摘要:有很多的擴(kuò)展在開發(fā)時(shí)未能考慮到并發(fā)性可重入問題,導(dǎo)致無法在協(xié)程中使用。本文會(huì)詳細(xì)講解如何編寫協(xié)程并發(fā)安全的代碼。協(xié)程將自身?xiàng)?nèi)存的指針發(fā)送給另外一個(gè)協(xié)程,協(xié)程退出時(shí)會(huì)釋放協(xié)程棧內(nèi)存。協(xié)程的生命周期長(zhǎng)于,繼續(xù)讀寫此內(nèi)存,就會(huì)導(dǎo)致。
Swoole4 協(xié)程的出現(xiàn)使得 PHP 底層上從原來串行模式變成了并發(fā)模式。有很多 PHP 的C/C++擴(kuò)展在開發(fā)時(shí)未能考慮到并發(fā)性、可重入問題,導(dǎo)致無法在Swoole協(xié)程中使用。本文會(huì)詳細(xì)講解如何編寫協(xié)程并發(fā)安全的C/C++代碼。
可重入性示例代碼:
int t; void test1(int *x, int *y) { t = *x; *x = *y; //fun1 函數(shù)中可能會(huì)存在協(xié)程切換 fun1(); //錯(cuò)誤代碼 *y = t; }
t是一個(gè)全局變量或者static靜態(tài)變量
在協(xié)程A中調(diào)用了test1函數(shù),使用了全局變量t
當(dāng)函數(shù)內(nèi)調(diào)用了fun1(),這個(gè)函數(shù)中如果發(fā)生了協(xié)程切換,這時(shí)假如另外一個(gè)協(xié)程B也執(zhí)行了test1函數(shù),那么t的值可能會(huì)被修改
協(xié)程B掛起時(shí),重新回到協(xié)程A,這時(shí)*y = t,會(huì)得到一個(gè)錯(cuò)誤的值
引用棧內(nèi)存這也是一個(gè)嚴(yán)重的風(fēng)險(xiǎn)點(diǎn)。協(xié)程1將自身?xiàng)?nèi)存的指針發(fā)送給另外一個(gè)協(xié)程2,協(xié)程1退出時(shí)會(huì)釋放協(xié)程棧內(nèi)存。協(xié)程2的生命周期長(zhǎng)于1,繼續(xù)讀寫此內(nèi)存,就會(huì)導(dǎo)致segment fault。
示例:
void co1() { char buf[2048]; //這里啟動(dòng)一個(gè)新的協(xié)程,buf 是協(xié)程1棧上內(nèi)存 co2(buf); //協(xié)程1 退出時(shí)會(huì)釋放棧內(nèi)存 } void co2(char *buf) { for(int i=0; i<2048; i++) { Coroutine::sleep(1); //這里 buf 內(nèi)存可能已經(jīng)釋放了 buf[i] = 1; } }協(xié)程安全代碼
為了保證安全性,在Swoole4協(xié)程編程中:
不要使用static變量和全局變量,堅(jiān)持只用局部變量
若必須訪問全局變量,必須保證只用于計(jì)算邏輯,不得存在任何IO或Sleep等引起協(xié)程切換的操作
不調(diào)用其它任何不可重入的函數(shù)
不要引用棧上內(nèi)存
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/31013.html
摘要:下文如無特殊聲明將使用進(jìn)程同時(shí)表示進(jìn)程線程。收到數(shù)據(jù)后服務(wù)器程序進(jìn)行處理然后使用向客戶端發(fā)送響應(yīng)。現(xiàn)在各種高并發(fā)異步的服務(wù)器程序都是基于實(shí)現(xiàn)的,比如。 并發(fā) IO 問題一直是服務(wù)器端編程中的技術(shù)難題,從最早的同步阻塞直接 Fork 進(jìn)程,到 Worker 進(jìn)程池/線程池,到現(xiàn)在的異步IO、協(xié)程。PHP 程序員因?yàn)橛袕?qiáng)大的 LAMP 框架,對(duì)這類底層方面的知識(shí)知之甚少,本文目的就是詳細(xì)介...
摘要:第一階段基礎(chǔ)階段基礎(chǔ)程序員重點(diǎn)把搞熟練核心是安裝配置基本操作目標(biāo)能夠完成基本的系統(tǒng)安裝,簡(jiǎn)單配置維護(hù)能夠做基本的簡(jiǎn)單系統(tǒng)的開發(fā)能夠在中型系統(tǒng)中支持某個(gè)功能模塊的開發(fā)。本項(xiàng)不做重點(diǎn)學(xué)習(xí),除非對(duì)前端有興趣。 第一階段:基礎(chǔ)階段(基礎(chǔ)PHP程序員) 重點(diǎn):把LNMP搞熟練(核心是安裝配置基本操作) 目標(biāo):能夠完成基本的LNMP系統(tǒng)安裝,簡(jiǎn)單配置維護(hù);能夠做基本的簡(jiǎn)單系統(tǒng)的PHP開發(fā);能夠在P...
閱讀 1335·2021-09-27 13:35
閱讀 2651·2021-09-06 15:12
閱讀 3452·2019-08-30 15:55
閱讀 2900·2019-08-30 15:43
閱讀 486·2019-08-29 16:42
閱讀 3505·2019-08-29 15:39
閱讀 3127·2019-08-29 12:28
閱讀 1303·2019-08-29 11:11