亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

啥是并發(fā)編程呢

指在一臺處理器上同時處理多個任務

此處說的同時,可不是同一個時間一起手拉手做同一件事情

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

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

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

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

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

充分的利用好處理器的每一個核,以達到最高的處理性能,盡可能的運用好每一塊磚

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

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

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

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

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

是 系統(tǒng)進行資源分配和調度的一個獨立單位。

線程是進程的一個執(zhí)行實體

是 CPU 調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。

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

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

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

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

并發(fā)

多線程程序在一個核的 CPU 上運行

并行

多線程程序在多個核的 CPU 上運行

并發(fā)就像多個小伙伴跑接力,同一個時間點只會有一個小伙伴在跑,互相有影響

并行就像是多個小伙伴同一個起點一起跑,互不干擾

我們需要記住一點,再強調一波:

并發(fā)不是并行

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

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

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

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

協(xié)程 goroutine 是啥

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

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

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

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

協(xié)程

獨立的棧空間,共享堆空間,調度由用戶自己控制

本質上有點類似于用戶級線程,這些用戶級線程的調度也是自己實現(xiàn)的。

線程

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

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

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

GOLANG并發(fā)編程涉及哪些知識點呢

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

Goroutine的那些事

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

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

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

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

GO里面就正好有這樣的機制

goroutine 的概念類似于線程

goroutine 是由Go的運行時(runtime)調度和管理的

Go程序會智能地將 goroutine 中的任務合理地分配給每個CPU

Go 在語言層面已經內置了調度和上下文切換的機制

寫 GO 比較爽的一個地方是:

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

我們可以使用 goroutine 包

如何使用 goroutine

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

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

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

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

啟動單個協(xié)程

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

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

this is Hi Goroutine!
main goroutine!

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

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

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

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

main goroutine!

在程序啟動的時候,Go 程序就會為 main() 函數(shù)創(chuàng)建一個默認的 goroutine 協(xié)程

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

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

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

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

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

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

多個協(xié)程

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

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

package main

import (
	"fmt"
	"sync"
)

var myWg sync.WaitGroup

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

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

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

會有如下輸出,每一個協(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ù)運行嗎?

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

GO 中的協(xié)程

分享如下幾個點

GO中的棧是可增長的

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

goroutine 是如何調度

這就不得不提 GPM

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

G

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

P

Processor 管理著一組 goroutine 隊列

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

P 會對自己管理的 goroutine 隊列做一些調度(比如把占用CPU時間較長的 goroutine 暫停、運行后續(xù)的 goroutine)

當自己的隊列消費完了就去全局隊列里取,如果全局隊列里也消費完了會去其他P的隊列里搶任務。

M(machine)

是 Go 運行時(runtime)對操作系統(tǒng)內核線程的虛擬

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

這里的 P 與 M 一般也是一一對應的

P 管理著一組G 掛載在 M 上運行

當一個 G 長久阻塞在一個 M 上時,runtime 會新建一個M,

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

這個時候,當舊的 G 阻塞完成或者認為其已經掛了的話,就會回收舊的 M

還有一點

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

總結

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

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

相關文章

  • Golang中的路由使用詳解

    Golang中的路由使用詳解

    這篇文章主要介紹了Golang中的路由使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 詳解如何使用Golang擴展Envoy

    詳解如何使用Golang擴展Envoy

    這篇文章主要為大家介紹了詳解如何使用Golang擴展Envoy實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Go gin框架處理panic的方法詳解

    Go gin框架處理panic的方法詳解

    本文我們介紹下recover在gin框架中的應用, 首先,在golang中,如果在子協(xié)程中遇到了panic,那么主協(xié)程也會被終止,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • Go實踐反向代理ReverseProxy解析

    Go實踐反向代理ReverseProxy解析

    這篇文章主要為大家介紹了Go實踐反向代理示例ReverseProxy解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Go語言驅動低代碼應用引擎工具Yao開發(fā)管理系統(tǒng)

    Go語言驅動低代碼應用引擎工具Yao開發(fā)管理系統(tǒng)

    這篇文章主要為大家介紹了Go語言驅動低代碼應用引擎工具Yao開發(fā)管理系統(tǒng)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Go語言實現(xiàn)AES加密并編寫一個命令行應用程序

    Go語言實現(xiàn)AES加密并編寫一個命令行應用程序

    密碼學中的高級加密標準(Advanced Encryption Standard,AES),又稱Rijndael加密法,是經常采用的一種區(qū)塊加密標準。本文就來用Go語言實現(xiàn)AES加密算法,需要的可以參考一下
    2023-02-02
  • 深入探究Golang中flag標準庫的使用

    深入探究Golang中flag標準庫的使用

    在本文中,我們將深入探討 flag 標準庫的實現(xiàn)原理和使用技巧,以幫助讀者更好地理解和掌握該庫的使用方法,文中的示例代碼講解詳細,感興趣的可以了解一下
    2023-04-04
  • Go排序算法通用qsort函數(shù)使用示例

    Go排序算法通用qsort函數(shù)使用示例

    這篇文章主要為大家介紹了Go排序算法通用qsort函數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Golang中基礎的命令行模塊urfave/cli的用法說明

    Golang中基礎的命令行模塊urfave/cli的用法說明

    這篇文章主要介紹了Golang中基礎的命令行模塊urfave/cli的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang并發(fā)讀取文件數(shù)據(jù)并寫入數(shù)據(jù)庫的項目實踐

    Golang并發(fā)讀取文件數(shù)據(jù)并寫入數(shù)據(jù)庫的項目實踐

    本文主要介紹了Golang并發(fā)讀取文件數(shù)據(jù)并寫入數(shù)據(jù)庫的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06

最新評論