最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

瞅一眼就能學(xué)會(huì)的GO并發(fā)編程使用教程

 更新時(shí)間:2023年02月24日 10:50:23   作者:阿兵云原生  
隨著互聯(lián)網(wǎng)的普及,互聯(lián)網(wǎng)用戶人數(shù)原來越多,這對(duì)系統(tǒng)的性能帶來了巨大的挑戰(zhàn)。這個(gè)時(shí)候就需要并發(fā)編程了,本文為大家整理了詳細(xì)的GO并發(fā)編程使用教程,讓你看完就能學(xué)會(huì)

GO的并發(fā)編程分享

之前我們分享了網(wǎng)絡(luò)編程,今天我們來看看GO的并發(fā)編程分享,我們先來看看他是個(gè)啥

啥是并發(fā)編程呢

指在一臺(tái)處理器上同時(shí)處理多個(gè)任務(wù)

此處說的同時(shí),可不是同一個(gè)時(shí)間一起手拉手做同一件事情

并發(fā)是在同一實(shí)體上的多個(gè)事件,而這個(gè)事件在同一時(shí)間間隔發(fā)生的,同一個(gè)時(shí)間段,有多個(gè)任務(wù)執(zhí)行,可是同一個(gè)時(shí)間點(diǎn),只有一個(gè)任務(wù)在執(zhí)行

為啥要有并發(fā)編程

隨著互聯(lián)網(wǎng)的普及,互聯(lián)網(wǎng)用戶人數(shù)原來越多,這對(duì)系統(tǒng)的性能帶來了巨大的挑戰(zhàn)。

我們要通過各種方式來高效利用硬件的性能(壓榨),從而提高系統(tǒng)的性能進(jìn)而提升用戶體驗(yàn),提升團(tuán)隊(duì)或者企業(yè)的競爭力。

并發(fā)是為了解決什么問題?目的是啥?

充分的利用好處理器的每一個(gè)核,以達(dá)到最高的處理性能,盡可能的運(yùn)用好每一塊磚

可是由于現(xiàn)在我們使用的CPU,內(nèi)存,IO三者之間速度不盡相同

我們?yōu)榱颂岣呦到y(tǒng)性能,計(jì)算機(jī)系統(tǒng)會(huì)將這三者速度進(jìn)行平衡,以達(dá)到最優(yōu)的效果,都有如下措施:

  • 操作系統(tǒng)增加了進(jìn)程、線程,以分時(shí)復(fù)用 CPU,進(jìn)而均衡 CPUI/O 設(shè)備的速度差異;
  • CPU 增加了緩存,以均衡與內(nèi)存的速度差異;
  • 編譯程序優(yōu)化指令執(zhí)行次序,使得緩存能夠得到更加合理地利用。

說到進(jìn)程和線程,他們都是干啥的呢,咱們順帶說一下?

進(jìn)程是程序在操作系統(tǒng)中的一次執(zhí)行過程

是 系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。

線程是進(jìn)程的一個(gè)執(zhí)行實(shí)體

是 CPU 調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。

一個(gè)進(jìn)程可以創(chuàng)建和撤銷多個(gè)線程, 并且同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。

講到并發(fā)編程不得不說并發(fā)和并行有啥區(qū)別?是不是總是有小伙伴弄不清楚他們到底是啥區(qū)別,好像一樣,又好像不一樣

并發(fā)和并行的區(qū)別

一言蔽之,區(qū)別如下:

并發(fā)

多線程程序在一個(gè)核的 CPU 上運(yùn)行

并行

多線程程序在多個(gè)核的 CPU 上運(yùn)行

并發(fā)就像多個(gè)小伙伴跑接力,同一個(gè)時(shí)間點(diǎn)只會(huì)有一個(gè)小伙伴在跑,互相有影響

并行就像是多個(gè)小伙伴同一個(gè)起點(diǎn)一起跑,互不干擾

我們需要記住一點(diǎn),再強(qiáng)調(diào)一波:

并發(fā)不是并行

并發(fā)主要由切換時(shí)間片來實(shí)現(xiàn)"同時(shí)"運(yùn)行

并行則是直接利用多核實(shí)現(xiàn)多線程的運(yùn)行,

在 GO 可以設(shè)置使用核數(shù),以發(fā)揮多核計(jì)算機(jī)的能力,不過設(shè)置核數(shù)都是依賴于硬件的

那么,講到GO的并發(fā)編程,就必須上我們的主角,那就是協(xié)程

協(xié)程 goroutine 是啥

協(xié)程是一種程序組件

是由子例程(過程、函數(shù)、例程、方法、子程序)的概念泛化而來的

子例程只有一個(gè)入口點(diǎn)且只返回一次,而協(xié)程允許多個(gè)入口點(diǎn),可以在指定位置掛起和恢復(fù)執(zhí)行。

協(xié)程和線程分別有啥特點(diǎn)嘞

協(xié)程

獨(dú)立的??臻g,共享堆空間,調(diào)度由用戶自己控制

本質(zhì)上有點(diǎn)類似于用戶級(jí)線程,這些用戶級(jí)線程的調(diào)度也是自己實(shí)現(xiàn)的。

線程

一個(gè)線程上可以跑多個(gè)協(xié)程,協(xié)程是輕量級(jí)的線程。

GO 高并發(fā)的原因是啥

  • goroutine 奉行通過通信來共享內(nèi)存
  • 每個(gè)一個(gè)GO的實(shí)例有4~5KB的棧內(nèi)存占用,并且由于 GO 實(shí)現(xiàn)機(jī)制而大幅減少的創(chuàng)建和銷毀開銷
  • Golang 在語言層面上就支持協(xié)程 goroutine

GOLANG并發(fā)編程涉及哪些知識(shí)點(diǎn)呢

  • 基本協(xié)程的原理,實(shí)現(xiàn)方式,雖然說,GO中使用協(xié)程很方便,可以我們必須要知其然而值其所以然
  • Goroutine 池
  • runtime 包的使用
  • Channel 通道
  • 定時(shí)器
  • 并發(fā)且安全的鎖
  • 原子操作
  • select 多路復(fù)用
  • 等等...

Goroutine的那些事

我們寫C/C++的時(shí)候,我們必然也是要實(shí)現(xiàn)并發(fā)編程

我們通常需要自己維護(hù)一個(gè)線程池,并且需要自己去包裝一個(gè)又一個(gè)的任務(wù),同時(shí)需要自己去調(diào)度線程執(zhí)行任務(wù)并維護(hù)上下文切換

且做線程池的時(shí)候,我們需要自己做一個(gè)線程管理的角色,靈活動(dòng)態(tài)壓縮和擴(kuò)容

可是能不能有這樣一種機(jī)制,我們只需要定義多個(gè)任務(wù),讓系統(tǒng)去幫助我們把這些任務(wù)分配到CPU上實(shí)現(xiàn)并發(fā)執(zhí)行

GO里面就正好有這樣的機(jī)制

goroutine 的概念類似于線程

goroutine 是由Go的運(yùn)行時(shí)(runtime)調(diào)度和管理的

Go程序會(huì)智能地將 goroutine 中的任務(wù)合理地分配給每個(gè)CPU

Go 在語言層面已經(jīng)內(nèi)置了調(diào)度和上下文切換的機(jī)制

寫 GO 比較爽的一個(gè)地方是:

在GO里面,你不需要去自己寫進(jìn)程、線程、協(xié)程

我們可以使用 goroutine 包

如何使用 goroutine

我們需要讓某個(gè)任務(wù)并發(fā)執(zhí)行的時(shí)候,只需要把這個(gè)任務(wù)包裝成一個(gè)函數(shù)

專門開啟一個(gè) goroutine 協(xié)程 去執(zhí)行這個(gè)函數(shù)就可以了 , GO一個(gè)協(xié)程,很方便

一個(gè) goroutine 必定對(duì)應(yīng)一個(gè)函數(shù),可以創(chuàng)建多個(gè) goroutine 去執(zhí)行相同的函數(shù),只是多個(gè)協(xié)程都是做同一個(gè)事情罷了

我們先來使用一下協(xié)程,再來拋磚引玉,適當(dāng)?shù)姆窒硪幌?/p>

啟動(dòng)單個(gè)協(xié)程

func Hi() {
    fmt.Println("this is Hi Goroutine!")
}
func main() {
    Hi()
    fmt.Println("main goroutine!")
}

我們一般調(diào)用函數(shù)是如上這個(gè)樣子的,效果如下

this is Hi Goroutine!
main goroutine!

其實(shí)我們調(diào)用協(xié)程的話,也與上述類似

我們可以使用 go 后面加上函數(shù)名字,來開辟一個(gè)協(xié)程,專門做函數(shù)需要執(zhí)行的事情

func main() {
    go Hi() // 啟動(dòng)一個(gè)goroutine 協(xié)程 去執(zhí)行 Hi 函數(shù)
    fmt.Println("main goroutine!")

實(shí)際效果我們可以看到,程序只打印了 main goroutine!

main goroutine!

在程序啟動(dòng)的時(shí)候,Go 程序就會(huì)為 main() 函數(shù)創(chuàng)建一個(gè)默認(rèn)的 goroutine 協(xié)程

當(dāng) main() 函數(shù)返回的時(shí)候,剛開辟的另外一個(gè) goroutine 協(xié)程 就結(jié)束了

所有在 main() 函數(shù)中啟動(dòng)的 goroutine 協(xié)程 會(huì)一同結(jié)束,老大死了,其余的傀儡也灰飛煙滅了

我們也可以讓主協(xié)程等等一定子協(xié)程,待子協(xié)程處理完自己的事情,退出后,主協(xié)程再自己退出,這和我們寫C/C++進(jìn)程 和 線程的時(shí)候,類似

簡單的,我們可以使用 time.sleep 函數(shù)來讓主協(xié)程阻塞等待

我們也可以使用 上述提到的 使用 select{} 來達(dá)到目的

當(dāng)然也有其他的方式,后續(xù)文章會(huì)慢慢的分享到

多個(gè)協(xié)程

那么多個(gè)協(xié)程又是怎么玩的呢?

我們使用 sync.WaitGroup 來實(shí)現(xiàn)goroutine 協(xié)程的同步

package main

import (
	"fmt"
	"sync"
)

var myWg sync.WaitGroup

func Hi(i int) {
	// goroutine 協(xié)程 結(jié)束就 記錄 -1
	defer myWg.Done()
	fmt.Println("Hello Goroutine! the ", i)
}
func main() {

	for i := 0; i < 10; i++ {
		// 啟動(dòng)一個(gè)goroutine 協(xié)程 就記錄 +1
		myWg.Add(1)
		go Hi(i)
	}

	// 等待所有記錄 的goroutine 協(xié)程 都結(jié)束
	myWg.Wait() 
}

會(huì)有如下輸出,每一個(gè)協(xié)程打印的數(shù)字并不是按照順序來的:

Hello Goroutine! the  9
Hello Goroutine! the  4
Hello Goroutine! the  2
Hello Goroutine! the  3
Hello Goroutine! the  6
Hello Goroutine! the  5
Hello Goroutine! the  7
Hello Goroutine! the  8
Hello Goroutine! the  1
Hello Goroutine! the  0

還是同樣的, 如果是主協(xié)程先退出,那么子協(xié)程還行繼續(xù)運(yùn)行嗎?

毋庸置疑,主協(xié)程退出,子協(xié)程也會(huì)跟著退出

GO 中的協(xié)程

分享如下幾個(gè)點(diǎn)

GO中的棧是可增長的

一般都有固定的棧內(nèi)存(通常為2MB),goroutine 的棧不是固定的,goroutine 的棧大小可以擴(kuò)展到1GB

goroutine 是如何調(diào)度

這就不得不提 GPM

GPM是Go語言運(yùn)行時(shí)(runtime)層面實(shí)現(xiàn)的,我們先簡單了解一下GPM分別代表啥

G

就是個(gè) goroutine ,里面除了存放本 goroutine 信息外 還有與所在P的綁定等信息

P

Processor 管理著一組 goroutine 隊(duì)列

P 里面會(huì)存儲(chǔ)當(dāng)前 goroutine 運(yùn)行的上下文環(huán)境(函數(shù)指針,堆棧地址及地址邊界)

P 會(huì)對(duì)自己管理的 goroutine 隊(duì)列做一些調(diào)度(比如把占用CPU時(shí)間較長的 goroutine 暫停、運(yùn)行后續(xù)的 goroutine)

當(dāng)自己的隊(duì)列消費(fèi)完了就去全局隊(duì)列里取,如果全局隊(duì)列里也消費(fèi)完了會(huì)去其他P的隊(duì)列里搶任務(wù)。

M(machine)

是 Go 運(yùn)行時(shí)(runtime)對(duì)操作系統(tǒng)內(nèi)核線程的虛擬

M 與內(nèi)核線程一般是一一映射的關(guān)系, 一個(gè) groutine 最終是要放到 M上執(zhí)行

這里的 P 與 M 一般也是一一對(duì)應(yīng)的

P 管理著一組G 掛載在 M 上運(yùn)行

當(dāng)一個(gè) G 長久阻塞在一個(gè) M 上時(shí),runtime 會(huì)新建一個(gè)M,

阻塞 G 所在的 P 會(huì)把其他的 G 掛載在新建的M上

這個(gè)時(shí)候,當(dāng)舊的 G 阻塞完成或者認(rèn)為其已經(jīng)掛了的話,就會(huì)回收舊的 M

還有一點(diǎn)

P 的個(gè)數(shù)是通過 runtime.GOMAXPROCS 設(shè)定(最大256),這個(gè)數(shù)字也依賴于自己的硬件,在并發(fā)量大的時(shí)候會(huì)增加一些 P 和 M ,但不會(huì)太多

總結(jié)

  • 分享了并發(fā)和并行
  • 分享了GO 的并發(fā),協(xié)程的簡單使用
  • 簡單分享了GO可伸縮擴(kuò)展的棧內(nèi)存

到此這篇關(guān)于瞅一眼就能學(xué)會(huì)的GO并發(fā)編程使用教程的文章就介紹到這了,更多相關(guān)GO并發(fā)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何在Go中使用Casbin進(jìn)行訪問控制

    如何在Go中使用Casbin進(jìn)行訪問控制

    這篇文章主要介紹了如何在Go中使用Casbin進(jìn)行訪問控制,Casbin是一個(gè)強(qiáng)大的、高效的開源訪問控制框架,其權(quán)限管理機(jī)制支持多種訪問控制模型,Casbin只負(fù)責(zé)訪問控制
    2022-08-08
  • golang接口IP限流,IP黑名單,IP白名單的實(shí)例

    golang接口IP限流,IP黑名單,IP白名單的實(shí)例

    這篇文章主要介紹了golang接口IP限流,IP黑名單,IP白名單的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 用go gin server來做文件上傳服務(wù)

    用go gin server來做文件上傳服務(wù)

    今天小編就為大家分享一篇關(guān)于用go gin server來做文件上傳服務(wù),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • gin正確多次讀取http?request?body內(nèi)容實(shí)現(xiàn)詳解

    gin正確多次讀取http?request?body內(nèi)容實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了gin正確多次讀取http?request?body內(nèi)容實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go設(shè)計(jì)模式之生成器模式詳細(xì)講解

    Go設(shè)計(jì)模式之生成器模式詳細(xì)講解

    生成器模式將一個(gè)復(fù)雜對(duì)象的構(gòu)建和它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。生成器模式的主要功能是構(gòu)建復(fù)雜的產(chǎn)品,而且是細(xì)化地、分步驟地構(gòu)建產(chǎn)品,也就是說生成器模式重在一步一步解決構(gòu)建復(fù)雜對(duì)象的問題
    2023-01-01
  • Go語言eclipse環(huán)境搭建圖文教程

    Go語言eclipse環(huán)境搭建圖文教程

    這篇文章主要介紹了Go語言eclipse環(huán)境搭建的方法,結(jié)合圖文形式詳細(xì)分析了在eclipse環(huán)境下開發(fā)Go語言所涉及的組件下載、安裝及相關(guān)設(shè)置方法,需要的朋友可以參考下
    2016-07-07
  • go nil處理如何正確返回nil的error

    go nil處理如何正確返回nil的error

    這篇文章主要為大家介紹了go中的nil處理,如何正確返回nil的error實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 一文帶你掌握Go語言并發(fā)模式中的Context的上下文管理

    一文帶你掌握Go語言并發(fā)模式中的Context的上下文管理

    在?Go?的日常開發(fā)中,Context?上下文對(duì)象無處不在,無論是處理網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫操作還是調(diào)用?RPC?等場景,那你真的熟悉它的正確用法嗎,隨著本文一探究竟吧
    2023-05-05
  • 深入了解GoLang中的工廠設(shè)計(jì)模式

    深入了解GoLang中的工廠設(shè)計(jì)模式

    這篇文章主要介紹了深入了解GoLang中的工廠設(shè)計(jì)模式,工廠模式是一種常用的設(shè)計(jì)模式,它屬于創(chuàng)建型模式,它的主要目的是封裝對(duì)象的創(chuàng)建過程,將對(duì)象的創(chuàng)建過程與對(duì)象的使用過程分離,從而提高代碼的可維護(hù)性和可擴(kuò)展性,需要詳細(xì)了解可以參考下文
    2023-05-05
  • 詳解Go語言的context包從放棄到入門

    詳解Go語言的context包從放棄到入門

    這篇文章主要介紹了Go語言的context包從放棄到入門,本文通過實(shí)例演示給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論

叙永县| 贞丰县| 云林县| 澎湖县| 德令哈市| 德昌县| 丽江市| 温泉县| 河北省| 东乡| 凉山| 玛曲县| 历史| 无极县| 通道| 临漳县| 玛曲县| 邻水| 华蓥市| 凌云县| 遂川县| 太仓市| 延庆县| 南漳县| 敦化市| 搜索| 曲松县| 左权县| 东明县| 攀枝花市| 满城县| 文水县| 中阳县| 台安县| 通榆县| 崇明县| 德州市| 邵阳市| 彭山县| 河源市| 会同县|