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