目錄
引言" >引言
goroutine" >goroutine
使用goroutine" >使用goroutine
普通呼叫函數方式" >普通呼叫函數方式
函數" >函數
main
" >main
函數還是上述的函數" >函數還是上述的函數
第6行,前面加了個go關鍵字,go關鍵字表示以一個微執行緒的方式單獨運行這個函數。 " >第6行,前面加了個go關鍵字,go關鍵字表示以一個微執行緒的方式單獨運行這個函數。
為什麼會出現0s這種情況" >為什麼會出現0s這種情況
sync .WaitGroup" >sync .WaitGroup
函数" >函数
执行结果
" >执行结果
runtime.GOMAXPROCS
" >runtime.GOMAXPROCS
首頁 後端開發 Golang 一篇文章帶你入門Go語言基礎之並發

一篇文章帶你入門Go語言基礎之並發

Jul 21, 2023 am 10:33 AM
go語言

引言

#Go語言,專門為並發而生的語言,每啟動一個微線程#創建一個代價大概2KB 開始

假設一個記憶體大小#4G,一個微線程2kb1G=1024M=1048576kb 1048576/2=524288,五十多萬個

但是你知道像Java,Python等語言,一個執行緒代價多大嗎???,2MB開始,代價直接翻了千倍

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

#

<br>

goroutine

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

##就像我用兩隻手同時操作兩個手機打遊戲一樣

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

goroutine由Go的runtime完成調度,goroutine的本質是在程式碼(使用者狀態)層級完成的切換,代價很小

像Java, Python等語言的線程,是在作業系統(核心狀態)層級完成的切花,所以代價非常大

由於goroutine是由runtime完成切換,而且runtime經過Google公司的數位大佬優化,已經很小母牛上山了,牛逼哄哄了。

<br>

使用goroutine

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

普通呼叫函數方式

函數

#
func Say() {
    time.Sleep(time.Second)
    fmt.Println("我在说话说了1s说完了...")
}
登入後複製

main


func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        Say()
}
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}
登入後複製

一篇文章帶你入門Go語言基礎之並發執行結果


#循環了10次,耗時10s,有點慢啊!

#goroutine呼叫函數方式

函數還是上述的函數

main

func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        go Say()
}
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}
登入後複製

#注意:

第6行,前面加了個go關鍵字,go關鍵字表示以一個微執行緒的方式單獨運行這個函數。

一篇文章帶你入門Go語言基礎之並發

執行結果################

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


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

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

一篇文章帶你入門Go語言基礎之並發

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

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

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


sync .WaitGroup

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

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

所以,有一个新的问题,那就是等,祭出法宝sync.WaitGroup

先看一下怎么用

函数

func Say() {
    //函数结束时取消标记
    defer wg.Done()
    //每个函数在启动时加上一个标记
    wg.Add(1)
    //函数开始打上一个标记
    time.Sleep(time.Second*1)
    fmt.Println("我在说话说了1s说完了...")
}
登入後複製

main

var wg  sync.WaitGroup
func main() {
    //开始时间
    var start_time = time.Now()
    //启动10个say说话
    for i := 0; i < 10; i++ {
        go Say()
}
    // 等待所有标记过的微线程执行完毕
    wg.Wait()
    //结束时间
    var end_time = time.Now()
    //计算时间差
    fmt.Println(end_time.Sub(start_time))
}
登入後複製

执行结果

一篇文章帶你入門Go語言基礎之並發

可以看到,10个线程同时启动,1s就完了,并且代码相对简单,就算开启10w个,还是1s多一点

这也是为什么很多公司越来越青睐Go的原因。

一篇文章帶你入門Go語言基礎之並發

runtime.GOMAXPROCS

这个意思要使用多少个核,默认使用全部核心,性能跑满,但是也有意外的情况,

比如一个机器跑了很多其他任务,Go写的这个是不太重要的任务,但是是计算型的,这时候理论来说是不尽量挤兑别人的算力

所以要限制一下当前程序使用电脑的算力

代码

func main() {
    //本机的cpu个数
    var cpuNum = runtime.NumCPU()
    fmt.Println(cpuNum)
    //设置Go使用cpu个数
    runtime.GOMAXPROCS(4)
}
登入後複製

<br>

总结<br>

上述我们学习了Go的并发,学习了

  • 如何创建一个协程(goroutine)。

  • 为什么需要sync.WaitGroup

  • 设置当前程序使用CPU核数。

以上是一篇文章帶你入門Go語言基礎之並發的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? 在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? Apr 02, 2025 pm 02:03 PM

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

使用 sql.Open 時,DSN 傳空為什麼不報錯? 使用 sql.Open 時,DSN 傳空為什麼不報錯? Apr 02, 2025 pm 12:54 PM

使用sql.Open時,DSN傳空為什麼不報錯?在Go語言中,sql.Open...

Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Apr 02, 2025 pm 12:57 PM

Go語言中結構體定義的兩種方式:var與type關鍵字的差異Go語言在定義結構體時,經常會看到兩種不同的寫法:一�...

See all articles