自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇文章帶你入門Go語言基礎之并發(fā)

開發(fā) 后端
終于到了Go中最牛掰的地方,并發(fā),這也是Go為什么能快速火的原因。今天就帶你入門Go語言基礎之并發(fā)。

[[359433]]

前言

Hey,大家好,我是碼農星期八,終于到了Go中最牛掰的地方,并發(fā),這也是Go為什么能快速火的原因。

部署方便,不需要容器,隨便跑一個都是相當于Nginx的存在,怎么肯能不火

所以,來看看吧!!!

引言

Go語言,專門為并發(fā)而生的語言,每啟動一個微線程創(chuàng)建一個代價大概2KB起步

假設一個內存條大小4G,一個微線程2kb,1G=1024M=1048576kb,1048576/2=524288,五十多萬個

但是你知道像Java,Python等語言,一個線程代價多大嗎???,2MB起步,代價直接翻了千倍

所以,激動吧,隨便用Go寫一個web程序,基本都相當于Nginx

goroutine

Go中的微線程,也叫做goroutine,goroutine是并行處理任務的

就像我用兩只手同時操作兩個手機打游戲一樣

而不是一個手玩玩這個,一個手玩玩那個,這樣切換式玩法

goroutine由Go的runtime完成調度,goroutine的本質是在代碼(用戶態(tài))級別完成的切換,代價很小

像Java,Python等語言的線程,是在操作系統(tǒng)(內核態(tài))級別完成的切花,所以代價非常大

由于goroutine是由runtime完成切換,并且runtime經過Google公司的數位大佬優(yōu)化,已經很小母牛上山了,牛逼哄哄了。

使用goroutine

在Go中使用goroutine很簡單,只需要在想調用的函數前加一個go就行了,這就代表啟動了一個goroutine

普通調用函數方式

函數

  1. func Say() { 
  2.     time.Sleep(time.Second
  3.     fmt.Println("我在說話說了1s說完了..."

  main

  1. func main() { 
  2.     //開始時間 
  3.     var start_time = time.Now() 
  4.     //啟動10個say說話 
  5.     for i := 0; i < 10; i++ { 
  6.         Say() 
  7.     //結束時間 
  8.     var end_time = time.Now() 
  9.     //計算時間差 
  10.     fmt.Println(end_time.Sub(start_time)) 

執(zhí)行結果


循環(huán)了10次,耗時10s,有點慢啊!

goroutine調用函數方式

函數還是上述的函數

main

  1. func main() { 
  2.     //開始時間 
  3.     var start_time = time.Now() 
  4.     //啟動10個say說話 
  5.     for i := 0; i < 10; i++ { 
  6.         go Say() 
  7.     //結束時間 
  8.     var end_time = time.Now() 
  9.     //計算時間差 
  10.     fmt.Println(end_time.Sub(start_time)) 

注意:第6行,前面加了個go關鍵字,go關鍵字就表示以一個微線程的方式單獨運行這個函數。

執(zhí)行結果


what??? 0s,什么情況?

為什么會出現0s這種情況

這是因為,在Go中,我們采用的是守護線程的方式,什么意思呢?


在Go中,main函數只要執(zhí)行完,其他微線程必涼。

就像有的怪獸,他們是互相依賴一個母體的,母體掛了,下面的娃也必掛。

所以該怎么解決這個問題呢???

sync.WaitGroup

上述我們發(fā)現,啟動了一些微線程,但是微線程還沒來得及執(zhí)行就掛了,是因為main函數跑的太快了,main跑完了,Go運行時自動將其他微線程關閉了。

那反過來想,我們如何讓main在最后等一下,等我的孩子們都回來了,我在繼續(xù)跑。

所以,有一個新的問題,那就是等,祭出法寶sync.WaitGroup

先看一下怎么用

函數

  1. func Say() { 
  2.     //函數結束時取消標記 
  3.     defer wg.Done() 
  4.     //每個函數在啟動時加上一個標記 
  5.     wg.Add(1) 
  6.     //函數開始打上一個標記 
  7.     time.Sleep(time.Second*1) 
  8.     fmt.Println("我在說話說了1s說完了..."

main

  1. var wg  sync.WaitGroup 
  2. func main() { 
  3.     //開始時間 
  4.     var start_time = time.Now() 
  5.     //啟動10個say說話 
  6.     for i := 0; i < 10; i++ { 
  7.         go Say() 
  8.     // 等待所有標記過的微線程執(zhí)行完畢 
  9.     wg.Wait() 
  10.     //結束時間 
  11.     var end_time = time.Now() 
  12.     //計算時間差 
  13.     fmt.Println(end_time.Sub(start_time)) 

執(zhí)行結果


可以看到,10個線程同時啟動,1s就完了,并且代碼相對簡單,就算開啟10w個,還是1s多一點

這也是為什么很多公司越來越青睞Go的原因。


runtime.GOMAXPROCS

這個意思要使用多少個核,默認使用全部核心,性能跑滿,但是也有意外的情況,

比如一個機器跑了很多其他任務,Go寫的這個是不太重要的任務,但是是計算型的,這時候理論來說是不盡量擠兌別人的算力

所以要限制一下當前程序使用電腦的算力

代碼

  1. func main() { 
  2.     //本機的cpu個數 
  3.     var cpuNum = runtime.NumCPU() 
  4.     fmt.Println(cpuNum) 
  5.     //設置Go使用cpu個數 
  6.     runtime.GOMAXPROCS(4) 

總結

上述我們學習了Go的并發(fā),學習了

  • 如何創(chuàng)建一個協(xié)程(goroutine)。
  • 為什么需要sync.WaitGroup。
  • 設置當前程序使用CPU核數。

在Go中,輕松實現一個高并發(fā)還是挺容易的,但是可能有些不是那么好理解。

 

責任編輯:姜華 來源: Go語言進階學習
相關推薦

2020-12-27 10:15:44

Go語言channel管道

2020-10-22 08:33:22

Go語言

2020-11-11 10:52:54

Go語言C語言

2020-11-05 09:58:16

Go語言Map

2022-02-16 10:03:06

對象接口代碼

2020-12-07 05:59:02

語言Go接口

2021-10-30 10:43:04

語言Go函數

2021-01-13 08:40:04

Go語言文件操作

2021-11-03 10:02:07

Go基礎函數

2022-04-27 10:01:43

切片Go封裝

2020-12-30 09:04:32

Go語言TCPUDP

2020-10-25 07:33:13

Go語言

2020-12-09 09:59:32

Go語言技術

2021-02-20 10:06:14

語言文件操作

2020-10-23 08:38:19

Go語言

2021-10-09 07:10:31

Go語言基礎

2021-10-16 10:17:51

Go語言數據類型

2020-10-22 11:15:47

Go語言變量

2021-09-29 10:00:07

Go語言基礎

2021-10-13 10:00:52

Go語言基礎
點贊
收藏

51CTO技術棧公眾號