日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

如果我必須選擇 Go 的一個偉大特性,那么它必須是內(nèi)置的并發(fā)模型。Go 不僅支持并發(fā)性,而且使其更好,更易于使用。Go 并發(fā)模型 (goroutine) 對并發(fā)編程的作用,就類似于 Docker 之于虛擬化的作用。

什么是并發(fā)

在計算機程序設(shè)計中,并發(fā)性指的是計算機同時處理多個任務(wù)的能力。例如,如果你在瀏覽器中上網(wǎng),可能會有很多事情同時在發(fā)生。比如,你正在下載一些文件,同時滾動頁面來收聽音樂。因此瀏覽器需要同時處理這兩件事情。如果瀏覽器無法處理這些問題,則需要等到所有下載任務(wù)完成,然后才能夠重新瀏覽網(wǎng)站,這對于用戶來說是一件很痛苦的事情。

一臺通用的 PC 機可能只有一個 CPU 核心來完成所有的任務(wù),一個 CPU 核心可以一次處理一件事。當我們討論并發(fā)性的時候,指的的是我們將 CPU 的時間片分配給需要處理的事情。因此,我們感覺到有很多事情在同時發(fā)生。

讓我們來看一個CPU管理web瀏覽器如何讓處理我們示例圖表中的內(nèi)容。

從上圖中,你可以看到一個單核處理器根據(jù)每個任務(wù)的優(yōu)先級來劃分工作負載。例如,當頁面滾動的時候,聽音樂的優(yōu)先級可能很低,因此有時你的音樂會因為網(wǎng)速低而停止,但是你仍然可以滾動頁面。單個處理器通過某種切換時間片調(diào)度任務(wù)執(zhí)行的策略,讓用戶感受到多個任務(wù)在同時執(zhí)行。

Go 并發(fā)編程的思考

 

什么是并行

接下來問題來了,如果我們CPU有多個內(nèi)核呢?實際上現(xiàn)代的CPU上都是多核架構(gòu),如果一個CPU有多個處理核心,我們就把它叫做“多核處理器”。你可能在購買電腦或者智能手機的時候聽說過這個詞,例如我目前工作的筆記本就是2核心的 ,相對于目前比較先進的個人電腦 CPU 來說,是很 LOW的了。而且

商用服務(wù)器一般達到了 64 核心的處理能力,多個處理其能夠同時處理多個任務(wù)。在前面 web 瀏覽器的示例中,我們的單核處理器必須將 CPU 時間分配給不同的任務(wù)對象。使用多核處理器,我們可以在不同的核中同時運行不同的任務(wù),可以看到下圖。

Go 并發(fā)編程的思考

 

同時運行多個任務(wù)的概念我們稱之為并行。當我們的 CPU 有多個內(nèi)核時,我們可以使用不同的 CPU 內(nèi)核來同時執(zhí)行多個任務(wù),因此我們可以很快的去完成一項包括很多任務(wù)的工作。

Go 并發(fā)編程的思考

 

并發(fā) vs 并行

Go 建議只在一個內(nèi)核上使用 goruntines,但是我們可以修改 Go 程序,以遍在不同的處理器內(nèi)核上運行 goruntines。

并發(fā)和并行之前有幾個區(qū)別。并發(fā)是交替的處理多個事情,并行則是同時處理多個事情。那是不是并行一定會被并發(fā)更有益呢?也不一定,我們會在后續(xù)的播客里面討論到這一點

現(xiàn)在,可能會有很多問題在你的腦海里飛舞,你可能已經(jīng)建立的并行和并發(fā)的想法,但你可能想知道如何使用 Go 的并發(fā)體系去實現(xiàn)它,在這之前我們先來了解一下計算機進程。

什么是計算機進程?

當你用 C、JAVA 或 Go 等語言編寫一個計算機程序時,它只是一個文本文件。但是由于計算機是只理解 0和1組成的二進制指令,所以需要將該代碼翻譯成機器語言。這就是編譯器的用武之地。在像 Python 和 js這樣的腳本語言中,解釋器做同樣的事情。 當編譯后的程序被發(fā)送到操作系統(tǒng)進行處理時,操作系統(tǒng)會分配不同的東西,比如內(nèi)存地址空間(進程的堆和堆棧位于其中)、程序計數(shù)器、進程id (PID) 和其他關(guān)鍵的東西。進程至少又一個稱之為主線程的線程,而主線程可以創(chuàng)建多個其他線程。當主線程執(zhí)行完成時,進程退出。

所以我們可以理解進程就是一個容器,它編譯了代碼,內(nèi)存、不同的操作系統(tǒng)資源和其他可以提供給線程的東西。簡而言之,進程就是內(nèi)存中的一個程序。

什么是計算機線程?

線程是一段代碼的實際執(zhí)行者。線程可以訪問進程提供的內(nèi)存、操作系統(tǒng)資源和其他東西。執(zhí)行程序代碼是,內(nèi)存區(qū)域內(nèi)的線程存儲變量(數(shù)據(jù))被稱為堆棧,其中暫存的變量占用堆棧空間,堆棧是在運行時創(chuàng)建的,通常具有固定大小,最好是1-2MB,線程堆棧只能由改線程使用,并且不會與其他線程共享。堆是進程的屬性,任何線程都可以使用它,堆是一個共享的內(nèi)存空間,一個線程中的數(shù)據(jù)也可以被其他線程訪問。

現(xiàn)在,我們對進程和線程有了一個大致的了解。但是它們有什么用呢?

當你啟動Web瀏覽器的時候,必須有一些調(diào)用os進程操作的代碼。這意味著我們正在創(chuàng)建一個進程,一個進程可能會操作 os 為新選項卡創(chuàng)建另一個進程。當瀏覽器選項卡打開并且您在執(zhí)行日常工作的時候,該選項卡將開始為不容的活動(如頁面滾動,下載,聽音樂等)創(chuàng)建不同的線程,就像我們前面的兩個進程處理任務(wù)圖里看到的那樣。 以下是 macOS 上Chrome瀏覽器應(yīng)用程序任務(wù)圖

該圖顯示了 google Chrome 瀏覽器對打開的標簽頁和內(nèi)部服務(wù)使用的不同進程。由于每個進程都至少又一個線程,因此我們可以看到線程數(shù)是大于進程數(shù)的。

Go 并發(fā)編程的思考

 

在多線程中,在一個進程中產(chǎn)生多個線程的情況下,具有內(nèi)存泄漏的線程可能會耗盡其他現(xiàn)層需要的資源而導(dǎo)致進程無響應(yīng)。使用瀏覽器或其他任何程序的時候,你可能都遇到過出現(xiàn)無響應(yīng)進程,任務(wù)管理器提示要將其殺死的現(xiàn)象。

線程調(diào)度

當多個線程串行或者并行運行的時候,由于多個線程之間可能共享一些數(shù)據(jù),因此線程之間需要協(xié)同工作,以便于一次只有一個線程可以訪問特定的數(shù)據(jù),保證任務(wù)的安全執(zhí)行。我們把以某種順序執(zhí)行多個線程稱為調(diào)度,操作系統(tǒng)線程由內(nèi)核調(diào)度,某些線程由編程語言(如:Java的運行時環(huán)境-JRE )的運行時環(huán)境管理。當多個線程試圖同時訪問同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)被更改或?qū)е乱馔饨Y(jié)果時,我們就說發(fā)生了爭用(race condition)。

當我們設(shè)計并發(fā)的 Go 程序時,關(guān)鍵在于尋找到這種爭用的情況,并且通過合理的措施才可以爭用情況下,多線程程序的安全運行。

Go 并發(fā)編程的思考

 

在 Go 中使用并發(fā)

接下來,我們來討論如何在 Go 代碼中實現(xiàn)并發(fā)。我們知道,在 Java, C++ 之類具有面向?qū)ο缶幊?OOP)特性的的語言中一般具有一個線程類,我們可以通過該類在當前進程中創(chuàng)建多個線程對象。由于 Go 語言沒有傳統(tǒng) OOP 語法,因此它提供了 go 關(guān)鍵字來創(chuàng)建 goruntine。當go關(guān)鍵字放在函數(shù)調(diào)用之前時,它將成為 goruntine 并被 go 調(diào)度執(zhí)行。

在后續(xù)的文章中,我們將單獨討論協(xié)程 goroutine (文中g(shù)oroutine和協(xié)程是等價的概念),目前你可以將它看作是一個線程,從技術(shù)上來講,協(xié)程的行為類似于線程,它是線程的抽象,下一小節(jié)將會介紹這兩者之間的區(qū)別。

當我們運行 Go 程序時,Go 運行時將在一個內(nèi)核上創(chuàng)建一定數(shù)量的線程。所有的 goruntine 在該內(nèi)核上進行多路復(fù)用。在任意時間點,一個線程執(zhí)行一個 goroutine,如果該 goroutine 被停止,則它將被換成在該線程上執(zhí)行另一個 goroutine。這有點類似于內(nèi)核的線程調(diào)度,但是由 Go 的運行時 (runtime) 處理,將比內(nèi)核調(diào)度更快。

建議在大多數(shù)的情況下,在一個內(nèi)核上運行所有的 goroutine,但是如果你需要在系統(tǒng)的多核內(nèi)核之前調(diào)度執(zhí)行 goroutine,則可以使用 GOMAXPROCS 環(huán)境變量控制,也可以使用runtime.GOMAXPROCS(n)(
https://golang.org/pkg/runtime/#GOMAXPROCS) 調(diào)節(jié)運行時環(huán)境,其中 n 就是你要使用的核心數(shù)。你可能會覺得將 GOMAXPROCS 設(shè)置成 1 使程序變慢。不過這不是絕對的,如何設(shè)置這個參數(shù)取決于你目前運行程序的性質(zhì),很有可能花在多個核之間的通信開銷要比你的運行開銷還要大,這時候操作系統(tǒng)線程和進程將會遇到性能下降的情況,同樣你的 Go 程序性能也就隨之下降了。 Go 有一個 M:N 調(diào)度程序,它可以調(diào)度 Go 程序在多個處理器上執(zhí)行。任何時候,都需要在 GOMAXPROCS 個處理器上運行 N 個操作系統(tǒng)線程上再調(diào)度 M 個協(xié)程 。在任何時候,每個內(nèi)核最多運行一個線程,但如果需要,調(diào)度程序可以創(chuàng)建更多的線程,但是這種情況很少發(fā)生。如果你的代碼里面沒有啟動任何的 goroutine,那么無論你是用多少個內(nèi)核,你的程序都只會在一個線程中、一個核上運行。

線程 vs 協(xié)程

由于線程和協(xié)程之間存在著明顯的區(qū)別,下面我們將通過對比項來解釋為什么線程開銷比協(xié)程更高,以及為什么協(xié)程是我們應(yīng)用程序?qū)崿F(xiàn)高級別并發(fā)特性的關(guān)鍵所在。

以上是幾個重要的區(qū)別,推薦你去深入的研究 Go 并發(fā)模型的實現(xiàn),它將會顛覆你對并發(fā)編程的理解。為了突出這個 Go 協(xié)程模型的強大,我們可以來分析一個案例。假設(shè)有一臺 web 服務(wù)器,每分鐘處理 1000 個請求。如果必須同時運行每個請求,則意味著你需要創(chuàng)建 1000 個線程或?qū)⑺鼈儎澐值讲煌倪M程中。這就是經(jīng)典服務(wù)器 Apache (https://www.apache.org/) 的做法,如果每個線程消耗 1MB 的堆棧大小,則意味著你將要使用 1GB 的內(nèi)存用于處理改流量。當然,Apache 提供了ThreadStackSize 指令來管理每個線程的堆棧大小,但是問題仍然沒有得到根本的解決。對于 Go 寫成來說,由于堆棧大小可以動態(tài)增長,因此,你可以毫無問題的生成 1000 個 goruntine 。由于 goruntine 的初始堆棧空間可以調(diào)節(jié),初始為8KB(更高的Go版本可能會更小),因此并不會消耗多大的內(nèi)存空間。同時當某個 goruntine 里面需要進行遞歸操作。Go可以輕松的將堆棧大小調(diào)大,可以達到1GB的大小,這樣無疑是“用更低的成本去做同樣的事情”。

Go 并發(fā)編程的思考

 

上面我們提到,一個線程上在一個時刻執(zhí)行運行一個協(xié)程,協(xié)程與協(xié)程之前是 Go 運行時來進行協(xié)同調(diào)度的。另一個協(xié)程不會被 “被占用的線程” 調(diào)度,知道在該線程上運行著的協(xié)程被阻塞。以下情況可以阻塞一個協(xié)程:

- 網(wǎng)絡(luò)流輸入

- 休眠 (sleeping)

- 通道 (channel) 操作

- 阻塞同步包 (
https://golang.org/pkg/sync/) 中的一些原語觸發(fā)

我們可以思考,假設(shè)協(xié)程不在上述情況下阻塞,那么阻塞住的協(xié)程將導(dǎo)致它所運行在的線程阻塞,殺掉其他需要調(diào)度的協(xié)程,我們需要通過詳細謹慎的編程手段來阻止這樣的事情發(fā)生。通道和同步原語在 Go 語言并發(fā)編程中扮演的舉足輕重的角色,后面我們將通過詳細的文章來分析它們的原理以及使用上的注意事項,這里不再過多闡述。

通過這篇文章,我們了解了線程調(diào)度的概念,以及 Go 中的并發(fā)使用和協(xié)程調(diào)度模型,最后我們對線程和協(xié)程進行了詳細的對比項,希望這些對比項可以幫助你在 Go 并發(fā)編程時做出更好的決策來使得程序達到更優(yōu)的性能。后續(xù)的文章,我們將給出一些實際的程序代碼來探索 Go 并發(fā)編程的奧秘,盡情期待。

分享到:
標簽:編程
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定