91精产品自偷自偷综合官网版下载-91精产品自偷自偷综合下-91精品-91精品91久久久-91精品成人-91精品成人www

網(wǎng)站建設(shè)資訊

NEWS

網(wǎng)站建設(shè)資訊

go語言中矩陣操作 go語言 range

【golang詳解】go語言GMP(GPM)原理和調(diào)度

Goroutine調(diào)度是一個很復(fù)雜的機制,下面嘗試用簡單的語言描述一下Goroutine調(diào)度機制,想要對其有更深入的了解可以去研讀一下源碼。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名注冊虛擬主機、營銷軟件、網(wǎng)站建設(shè)、王屋網(wǎng)站維護(hù)、網(wǎng)站推廣。

首先介紹一下GMP什么意思:

G ----------- goroutine: 即Go協(xié)程,每個go關(guān)鍵字都會創(chuàng)建一個協(xié)程。

M ---------- thread內(nèi)核級線程,所有的G都要放在M上才能運行。

P ----------- processor處理器,調(diào)度G到M上,其維護(hù)了一個隊列,存儲了所有需要它來調(diào)度的G。

Goroutine 調(diào)度器P和 OS 調(diào)度器是通過 M 結(jié)合起來的,每個 M 都代表了 1 個內(nèi)核線程,OS 調(diào)度器負(fù)責(zé)把內(nèi)核線程分配到 CPU 的核上執(zhí)行

模型圖:

避免頻繁的創(chuàng)建、銷毀線程,而是對線程的復(fù)用。

1)work stealing機制

當(dāng)本線程無可運行的G時,嘗試從其他線程綁定的P偷取G,而不是銷毀線程。

2)hand off機制

當(dāng)本線程M0因為G0進(jìn)行系統(tǒng)調(diào)用阻塞時,線程釋放綁定的P,把P轉(zhuǎn)移給其他空閑的線程執(zhí)行。進(jìn)而某個空閑的M1獲取P,繼續(xù)執(zhí)行P隊列中剩下的G。而M0由于陷入系統(tǒng)調(diào)用而進(jìn)被阻塞,M1接替M0的工作,只要P不空閑,就可以保證充分利用CPU。M1的來源有可能是M的緩存池,也可能是新建的。當(dāng)G0系統(tǒng)調(diào)用結(jié)束后,根據(jù)M0是否能獲取到P,將會將G0做不同的處理:

如果有空閑的P,則獲取一個P,繼續(xù)執(zhí)行G0。

如果沒有空閑的P,則將G0放入全局隊列,等待被其他的P調(diào)度。然后M0將進(jìn)入緩存池睡眠。

如下圖

GOMAXPROCS設(shè)置P的數(shù)量,最多有GOMAXPROCS個線程分布在多個CPU上同時運行

在Go中一個goroutine最多占用CPU 10ms,防止其他goroutine被餓死。

具體可以去看另一篇文章

【Golang詳解】go語言調(diào)度機制 搶占式調(diào)度

當(dāng)創(chuàng)建一個新的G之后優(yōu)先加入本地隊列,如果本地隊列滿了,會將本地隊列的G移動到全局隊列里面,當(dāng)M執(zhí)行work stealing從其他P偷不到G時,它可以從全局G隊列獲取G。

協(xié)程經(jīng)歷過程

我們創(chuàng)建一個協(xié)程 go func()經(jīng)歷過程如下圖:

說明:

這里有兩個存儲G的隊列,一個是局部調(diào)度器P的本地隊列、一個是全局G隊列。新創(chuàng)建的G會先保存在P的本地隊列中,如果P的本地隊列已經(jīng)滿了就會保存在全局的隊列中;處理器本地隊列是一個使用數(shù)組構(gòu)成的環(huán)形鏈表,它最多可以存儲 256 個待執(zhí)行任務(wù)。

G只能運行在M中,一個M必須持有一個P,M與P是1:1的關(guān)系。M會從P的本地隊列彈出一個可執(zhí)行狀態(tài)的G來執(zhí)行,如果P的本地隊列為空,就會想其他的MP組合偷取一個可執(zhí)行的G來執(zhí)行;

一個M調(diào)度G執(zhí)行的過程是一個循環(huán)機制;會一直從本地隊列或全局隊列中獲取G

上面說到P的個數(shù)默認(rèn)等于CPU核數(shù),每個M必須持有一個P才可以執(zhí)行G,一般情況下M的個數(shù)會略大于P的個數(shù),這多出來的M將會在G產(chǎn)生系統(tǒng)調(diào)用時發(fā)揮作用。類似線程池,Go也提供一個M的池子,需要時從池子中獲取,用完放回池子,不夠用時就再創(chuàng)建一個。

work-stealing調(diào)度算法:當(dāng)M執(zhí)行完了當(dāng)前P的本地隊列隊列里的所有G后,P也不會就這么在那躺尸啥都不干,它會先嘗試從全局隊列隊列尋找G來執(zhí)行,如果全局隊列為空,它會隨機挑選另外一個P,從它的隊列里中拿走一半的G到自己的隊列中執(zhí)行。

如果一切正常,調(diào)度器會以上述的那種方式順暢地運行,但這個世界沒這么美好,總有意外發(fā)生,以下分析goroutine在兩種例外情況下的行為。

Go runtime會在下面的goroutine被阻塞的情況下運行另外一個goroutine:

用戶態(tài)阻塞/喚醒

當(dāng)goroutine因為channel操作或者network I/O而阻塞時(實際上golang已經(jīng)用netpoller實現(xiàn)了goroutine網(wǎng)絡(luò)I/O阻塞不會導(dǎo)致M被阻塞,僅阻塞G,這里僅僅是舉個栗子),對應(yīng)的G會被放置到某個wait隊列(如channel的waitq),該G的狀態(tài)由_Gruning變?yōu)開Gwaitting,而M會跳過該G嘗試獲取并執(zhí)行下一個G,如果此時沒有可運行的G供M運行,那么M將解綁P,并進(jìn)入sleep狀態(tài);當(dāng)阻塞的G被另一端的G2喚醒時(比如channel的可讀/寫通知),G被標(biāo)記為,嘗試加入G2所在P的runnext(runnext是線程下一個需要執(zhí)行的 Goroutine。), 然后再是P的本地隊列和全局隊列。

系統(tǒng)調(diào)用阻塞

當(dāng)M執(zhí)行某一個G時候如果發(fā)生了阻塞操作,M會阻塞,如果當(dāng)前有一些G在執(zhí)行,調(diào)度器會把這個線程M從P中摘除,然后再創(chuàng)建一個新的操作系統(tǒng)的線程(如果有空閑的線程可用就復(fù)用空閑線程)來服務(wù)于這個P。當(dāng)M系統(tǒng)調(diào)用結(jié)束時候,這個G會嘗試獲取一個空閑的P執(zhí)行,并放入到這個P的本地隊列。如果獲取不到P,那么這個線程M變成休眠狀態(tài), 加入到空閑線程中,然后這個G會被放入全局隊列中。

隊列輪轉(zhuǎn)

可見每個P維護(hù)著一個包含G的隊列,不考慮G進(jìn)入系統(tǒng)調(diào)用或IO操作的情況下,P周期性的將G調(diào)度到M中執(zhí)行,執(zhí)行一小段時間,將上下文保存下來,然后將G放到隊列尾部,然后從隊列中重新取出一個G進(jìn)行調(diào)度。

除了每個P維護(hù)的G隊列以外,還有一個全局的隊列,每個P會周期性地查看全局隊列中是否有G待運行并將其調(diào)度到M中執(zhí)行,全局隊列中G的來源,主要有從系統(tǒng)調(diào)用中恢復(fù)的G。之所以P會周期性地查看全局隊列,也是為了防止全局隊列中的G被餓死。

除了每個P維護(hù)的G隊列以外,還有一個全局的隊列,每個P會周期性地查看全局隊列中是否有G待運行并將其調(diào)度到M中執(zhí)行,全局隊列中G的來源,主要有從系統(tǒng)調(diào)用中恢復(fù)的G。之所以P會周期性地查看全局隊列,也是為了防止全局隊列中的G被餓死。

M0

M0是啟動程序后的編號為0的主線程,這個M對應(yīng)的實例會在全局變量rutime.m0中,不需要在heap上分配,M0負(fù)責(zé)執(zhí)行初始化操作和啟動第一個G,在之后M0就和其他的M一樣了

G0

G0是每次啟動一個M都會第一個創(chuàng)建的goroutine,G0僅用于負(fù)責(zé)調(diào)度G,G0不指向任何可執(zhí)行的函數(shù),每個M都會有一個自己的G0,在調(diào)度或系統(tǒng)調(diào)用時會使用G0的棧空間,全局變量的G0是M0的G0

一個G由于調(diào)度被中斷,此后如何恢復(fù)?

中斷的時候?qū)⒓拇嫫骼锏臈P畔ⅲ4娴阶约旱腉對象里面。當(dāng)再次輪到自己執(zhí)行時,將自己保存的棧信息復(fù)制到寄存器里面,這樣就接著上次之后運行了。

我這里只是根據(jù)自己的理解進(jìn)行了簡單的介紹,想要詳細(xì)了解有關(guān)GMP的底層原理可以去看Go調(diào)度器 G-P-M 模型的設(shè)計者的文檔或直接看源碼

參考: ()

()

GO語言(十六):模糊測試入門(上)

本教程介紹了 Go 中模糊測試的基礎(chǔ)知識。通過模糊測試,隨機數(shù)據(jù)會針對您的測試運行,以嘗試找出漏洞或?qū)е卤罎⒌妮斎搿?梢酝ㄟ^模糊測試發(fā)現(xiàn)的一些漏洞示例包括 SQL 注入、緩沖區(qū)溢出、拒絕服務(wù)和跨站點腳本攻擊。

在本教程中,您將為一個簡單的函數(shù)編寫一個模糊測試,運行 go 命令,并調(diào)試和修復(fù)代碼中的問題。

首先,為您要編寫的代碼創(chuàng)建一個文件夾。

1、打開命令提示符并切換到您的主目錄。

在 Linux 或 Mac 上:

在 Windows 上:

2、在命令提示符下,為您的代碼創(chuàng)建一個名為 fuzz 的目錄。

3、創(chuàng)建一個模塊來保存您的代碼。

運行g(shù)o mod init命令,為其提供新代碼的模塊路徑。

接下來,您將添加一些簡單的代碼來反轉(zhuǎn)字符串,稍后我們將對其進(jìn)行模糊測試。

在此步驟中,您將添加一個函數(shù)來反轉(zhuǎn)字符串。

a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個名為 main.go 的文件。

獨立程序(與庫相反)始終位于 package 中main。

此函數(shù)將接受string,使用byte進(jìn)行循環(huán) ,并在最后返回反轉(zhuǎn)的字符串。

此函數(shù)將運行一些Reverse操作,然后將輸出打印到命令行。這有助于查看運行中的代碼,并可能有助于調(diào)試。

e.該main函數(shù)使用 fmt 包,因此您需要導(dǎo)入它。

第一行代碼應(yīng)如下所示:

從包含 main.go 的目錄中的命令行,運行代碼。

可以看到原來的字符串,反轉(zhuǎn)它的結(jié)果,然后再反轉(zhuǎn)它的結(jié)果,就相當(dāng)于原來的了。

現(xiàn)在代碼正在運行,是時候測試它了。

在這一步中,您將為Reverse函數(shù)編寫一個基本的單元測試。

a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個名為 reverse_test.go 的文件。

b.將以下代碼粘貼到 reverse_test.go 中。

這個簡單的測試將斷言列出的輸入字符串將被正確反轉(zhuǎn)。

使用運行單元測試go test

接下來,您將單元測試更改為模糊測試。

單元測試有局限性,即每個輸入都必須由開發(fā)人員添加到測試中。模糊測試的一個好處是它可以為您的代碼提供輸入,并且可以識別您提出的測試用例沒有達(dá)到的邊緣用例。

在本節(jié)中,您將單元測試轉(zhuǎn)換為模糊測試,這樣您就可以用更少的工作生成更多的輸入!

請注意,您可以將單元測試、基準(zhǔn)測試和模糊測試保存在同一個 *_test.go 文件中,但對于本示例,您將單元測試轉(zhuǎn)換為模糊測試。

在您的文本編輯器中,將 reverse_test.go 中的單元測試替換為以下模糊測試。

Fuzzing 也有一些限制。在您的單元測試中,您可以預(yù)測Reverse函數(shù)的預(yù)期輸出,并驗證實際輸出是否滿足這些預(yù)期。

例如,在測試用例Reverse("Hello, world")中,單元測試將返回指定為"dlrow ,olleH".

模糊測試時,您無法預(yù)測預(yù)期輸出,因為您無法控制輸入。

但是,Reverse您可以在模糊測試中驗證函數(shù)的一些屬性。在這個模糊測試中檢查的兩個屬性是:

(1)將字符串反轉(zhuǎn)兩次保留原始值

(2)反轉(zhuǎn)的字符串將其狀態(tài)保留為有效的 UTF-8。

注意單元測試和模糊測試之間的語法差異:

(3)確保新包unicode/utf8已導(dǎo)入。

隨著單元測試轉(zhuǎn)換為模糊測試,是時候再次運行測試了。

a.在不進(jìn)行模糊測試的情況下運行模糊測試,以確保種子輸入通過。

如果您在該文件中有其他測試,您也可以運行g(shù)o test -run=FuzzReverse,并且您只想運行模糊測試。

b.運行FuzzReverse模糊測試,查看是否有任何隨機生成的字符串輸入會導(dǎo)致失敗。這是使用go test新標(biāo)志-fuzz執(zhí)行的。

模糊測試時發(fā)生故障,導(dǎo)致問題的輸入被寫入將在下次運行的種子語料庫文件中g(shù)o test,即使沒有-fuzz標(biāo)志也是如此。要查看導(dǎo)致失敗的輸入,請在文本編輯器中打開寫入 testdata/fuzz/FuzzReverse 目錄的語料庫文件。您的種子語料庫文件可能包含不同的字符串,但格式相同。

語料庫文件的第一行表示編碼版本。以下每一行代表構(gòu)成語料庫條目的每種類型的值。由于 fuzz target 只需要 1 個輸入,因此版本之后只有 1 個值。

c.運行沒有-fuzz標(biāo)志的go test; 新的失敗種子語料庫條目將被使用:

由于我們的測試失敗,是時候調(diào)試了。

Go語言的特點

類型 在變量名后邊

也可不顯式聲明類型, 類型推斷, 但是是靜態(tài)語言, name一開始放字符串就不能再賦值數(shù)字

方法,屬性 分開 方法名首字母大寫就是就是外部可調(diào)的

面向?qū)ο笤O(shè)計的一個重要原則:“優(yōu)先使用組合而不是繼承”

Dog 也是Animal , 要復(fù)用Animal 的屬性和方法,

只需要在結(jié)構(gòu)體 type 里面寫 Animal

入口也是main, 用用試試

多態(tài), 有這個方法就是這個接口的實現(xiàn), 具體的類 不需要知道自己實現(xiàn)了什么接口,

使用: 在一個函數(shù)調(diào)用之前加上關(guān)鍵字go 就啟動了一個goroutine

創(chuàng)建一個goroutine,它會被加入到一個全局的運行隊列當(dāng)中,

調(diào)度器 會把他們分配給某個 邏輯處理器 的隊列,

一個邏輯處理器 綁定到一個 操作系統(tǒng)線程 ,在上面運行g(shù)oroutine,

如果goroutine需要讀寫文件, 阻塞 ,就脫離邏輯處理器 直接 goroutine - 系統(tǒng)線程 綁定

編譯成同名.exe 來執(zhí)行, 不通過虛擬機, 直接是機器碼, 和C 一樣, 所以非常快

但是也有自動垃圾回收,每個exe文件當(dāng)中已經(jīng)包含了一個類似于虛擬機的runtime,進(jìn)行g(shù)oroutine的調(diào)度

默認(rèn)是靜態(tài)鏈接的,那個exe會把運行時所需要的所有東西都加進(jìn)去,這樣就可以把exe復(fù)制到任何地方去運行了, 因此 生成的 .exe 文件非常大


分享題目:go語言中矩陣操作 go語言 range
文章源于:http://www.yuzhuanjia.cn/article/ddsshjh.html
主站蜘蛛池模板: www.中文字幕一区二区 | 高清国产动漫大全 | 国产av永久无码天堂影院 | 99re5久久在热线播放 | 91免费国产视频久久久 | 99久久精品亚洲欧美另类 | 高清无码在线免费 | 97国产精品视频人人做人人爱 | 午夜伦欧美理片848 午夜伦情电午夜伦情电影 午夜伦情电午夜伦情电影8090动漫在线观看 | 国产av演绎护士的遭遇 | AV久久无码| 91香蕉成人免费高清网站 | av无码a在线观看 | 海角国精产品一区一区三区糖心行业总结 | 91精品91 | 91免费在线视 | 91一区二区在线播放 | 国产91在| caoporn超频在线视频 | 午夜男女爽爽羞羞影院在线观看 | 国产va免费精品高清在线观看 | www色视频 | 午夜福利伦伦电影理论片在线观看 | 午夜国产美女三级毛片 | heyzo中文字幕 | ā片在线观看免费观看 | 99精品人妻少妇一区二区 | 日韩av无码成人无码免费 | 福利区体验区120秒免费 | 粗大猛烈进| 99久久久无码国产精品性蜜奴 | 伴郎粗大的内捧猛烈进出视频观看 | 91精品久久久久精品电影免费在线 | 国产av福利久久精品can动漫 | 91探花国产综合在线精 | 变态潮喷失禁大喷水 | 99久久伊人一区二区 | 99久久婷婷国产综合精品青草免费 | 91麻豆精品国产91久久久 | 91麻豆精品国产91久 | 久久99国产|