0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Go語(yǔ)言sync包中的鎖都在什么場(chǎng)景下用

馬哥Linux運(yùn)維 ? 來(lái)源:JWang的博客 ? 作者:JWang ? 2021-10-26 09:35 ? 次閱讀

Go 語(yǔ)言 sync 包中的鎖都在什么場(chǎng)景下用?怎么用?本文對(duì) sync 包內(nèi)的鎖做了梳理。

今天談一下鎖,以及 Go 里面 Sync 包里面自帶的各種鎖,說(shuō)到鎖這個(gè)概念,在日常生活中,鎖是為了保護(hù)一些東西,比如門鎖、密碼箱鎖,可以理解對(duì)資源的保護(hù)。在編程里面,鎖也是為了保護(hù)資源,比如說(shuō)對(duì)文件加鎖,同一時(shí)間只也許一個(gè)用戶修改,這種鎖一般叫作文件鎖。

實(shí)際開(kāi)發(fā)中,鎖又可分為互斥鎖(排它鎖)、讀寫(xiě)鎖、共享鎖、自旋鎖,甚至還有悲觀鎖、樂(lè)觀鎖這種說(shuō)法。在 Mysql 數(shù)據(jù)庫(kù)里面鎖的應(yīng)用更多,比如行鎖、表鎖、間隙鎖,有點(diǎn)眼花繚亂。拋開(kāi)這些概念,在編程領(lǐng)域,鎖的本質(zhì)是為了解決并發(fā)情況下對(duì)數(shù)據(jù)資源的訪問(wèn)問(wèn)題,如果我們不加鎖,并發(fā)讀寫(xiě)一塊數(shù)據(jù)必然會(huì)產(chǎn)生問(wèn)題,如果直接加個(gè)互斥鎖問(wèn)題是解決了,但是會(huì)嚴(yán)重影響讀寫(xiě)性能,所以后面又產(chǎn)生了更復(fù)雜的鎖機(jī)制,在數(shù)據(jù)安全性和性能之間找到最佳平衡點(diǎn)。

正常來(lái)說(shuō),只有在并發(fā)編程下才會(huì)需要鎖,比如說(shuō)多個(gè)線程(在 Go 里面則是協(xié)程)同時(shí)讀寫(xiě)一個(gè)文件,下面我以一個(gè)文件為例,來(lái)解釋這幾種鎖的概念:

如果我們使用互斥鎖,那么同一時(shí)間只能由一線程去操作(讀或?qū)懀?,這就是像是咱們?nèi)ド蠋?,一個(gè)坑位同一時(shí)間只能蹲一個(gè)人,這就是廁所門鎖的作用。

如果我們使用讀寫(xiě)鎖,意味著可以同時(shí)有多個(gè)線程讀取這個(gè)文件,但是寫(xiě)的時(shí)候不能讀,并且只能由一個(gè)線程去寫(xiě)。這個(gè)鎖實(shí)際上是互斥鎖的改進(jìn)版,很多時(shí)候我們之所以給文件加鎖是為了避免你在寫(xiě)的過(guò)程中有人讀到了臟數(shù)據(jù)。

如果我們使用共享鎖,根據(jù)我查到資料,這種叫法大多數(shù)是源自 MySQL 事務(wù)里面的鎖概念,它意味著只能讀數(shù)據(jù),并不能修改數(shù)據(jù)。

如果我們使用自旋鎖,則意味著當(dāng)一個(gè)線程在獲取鎖的時(shí)候,如果鎖已經(jīng)被其它線程獲取,那么該線程將循環(huán)等待,然后不斷的判斷鎖是否能夠被成功獲取,直到獲取到鎖才會(huì)退出循環(huán)。

這些鎖的機(jī)制在 Go 里面有什么應(yīng)用呢,下面大家一起看看 Go 標(biāo)準(zhǔn)庫(kù)里面 sync 包提供的一些非常強(qiáng)大的基于鎖的實(shí)現(xiàn)。

1. 文件鎖

文件鎖和 sync 包沒(méi)關(guān)系,這里面只是順便說(shuō)一下,舉個(gè)例子,磁盤(pán)上面有一個(gè)文件,必須保證同一時(shí)間只能由一個(gè)人打開(kāi),這里的同一時(shí)間是指操作系統(tǒng)層面的,并不是指應(yīng)用層面,文件鎖依賴于操作系統(tǒng)實(shí)現(xiàn)。

在 C 或 PHP 里面,文件鎖會(huì)使用一個(gè) flock 的函數(shù)去實(shí)現(xiàn),其實(shí) Go 里面也類似:

funcmain(){
varf="/var/logs/app.log"
file,err:=os.OpenFile(f,os.O_RDWR,os.ModeExclusive)
iferr!=nil{
panic(err)
}
deferfile.Close()

//調(diào)用系統(tǒng)調(diào)用加鎖
err=syscall.Flock(int(file.Fd()),syscall.LOCK_EX|syscall.LOCK_NB)
iferr!=nil{
panic(err)
}
defersyscall.Flock(int(file.Fd()),syscall.LOCK_UN)
//讀取文件內(nèi)容
all,err:=ioutil.ReadAll(file)
iferr!=nil{
panic(err)
}

fmt.Printf("%s",all)
time.Sleep(time.Second*10)//模擬耗時(shí)操作
}

需要說(shuō)明一下,F(xiàn)lock 函數(shù)第一個(gè)參數(shù)是文件描述符,第二個(gè)參數(shù)是鎖的類型,分為 LOCK_EX(排它鎖)、LOCK_SH(讀共享鎖)、LOCK_NB(遭遇鎖的表現(xiàn),遇到排它鎖的時(shí)候默認(rèn)會(huì)被阻塞,NB 即非阻塞,直接返回 Error)、LOCK_UN(解鎖)。

如果這時(shí)候你打開(kāi)另外一個(gè)終端再次運(yùn)行這個(gè)程序你會(huì)發(fā)現(xiàn)報(bào)錯(cuò)信息如下:

panic:resourcetemporarilyunavailable

文件鎖保證了一個(gè)文件在操作系統(tǒng)層面的數(shù)據(jù)讀寫(xiě)安全,不過(guò)實(shí)際應(yīng)用中并不常見(jiàn),畢竟大部分時(shí)候我們都是使用數(shù)據(jù)庫(kù)去做數(shù)據(jù)存儲(chǔ),極少使用文件。

2.sync.Mutex

下面我所說(shuō)的這些鎖都是應(yīng)用級(jí)別的鎖,位于 Go 標(biāo)準(zhǔn)庫(kù) sync 包里面,各有各的應(yīng)用場(chǎng)景。

這是一個(gè)標(biāo)準(zhǔn)的互斥鎖,平時(shí)用的也比較多,用法也非常簡(jiǎn)單,lock 用于加鎖,unlock 用于解鎖,配合 defer 使用,完美。

為了更好的展示鎖的應(yīng)用,這個(gè)舉一個(gè)沒(méi)有實(shí)際意義的例子,給一個(gè) int 變量做加法,用 2 個(gè)協(xié)程并發(fā)的去做加法。

variint

funcmain(){
goadd(&i)

time.Sleep(time.Second*3)

println(i)
}

funcadd(i*int){
forj:=0;j10000;j++{
*i=*i+1
}
}

我們想要得到的正常結(jié)果是 20000,然而實(shí)際上并不是,其結(jié)果是不固定的,很可能少于 20000,大家多運(yùn)行幾次便可得知。

假設(shè)你多加一行 runtime.GOMAXPROCS(1),你會(huì)發(fā)現(xiàn)結(jié)果一直是正確的,這是為什么呢?

用一個(gè)比較理論的說(shuō)法,這是因?yàn)楫a(chǎn)生了數(shù)據(jù)競(jìng)爭(zhēng)(data race)問(wèn)題,在 Go 里面我們可以在 go run 后面加上-race來(lái)檢測(cè)數(shù)據(jù)競(jìng)爭(zhēng),結(jié)果會(huì)告訴你在哪一行產(chǎn)生的,非常實(shí)用。

gorun-racemain.go
==================
WARNING:DATARACE
Readat0x00000056ccb8bygoroutine7:
main.add()
main.go:23+0x43
Previouswriteat0x00000056ccb8bygoroutine6:
main.add()
main.go:23+0x59
Goroutine7(running)createdat:
main.main()
main.go:14+0x76
Goroutine6(running)createdat:
main.main()
main.go:13+0x52
==================
20000
Found1datarace(s)
exitstatus66

解決這個(gè)問(wèn)題,有多種解法,我們當(dāng)然可以換個(gè)寫(xiě)法,比如說(shuō)用 chan 管道去做加法(chan 底層也用了鎖),實(shí)際上在 Go 里面更推薦去使用 chan 解決數(shù)據(jù)同步問(wèn)題,而不是直接用鎖機(jī)制。

在上面的這個(gè)例子里面我們需要在 add 方法里面寫(xiě),每次操作之前 lock,然后 unlock:

funcadd(i*int){
forj:=0;j10000;j++{
s.Lock()
*i=*i+1
s.Unlock()
}
}

3.sync.RWMutex

讀寫(xiě)鎖是互斥鎖的升級(jí)版,它最大的優(yōu)點(diǎn)就是支持多讀,但是讀和寫(xiě)、以及寫(xiě)與寫(xiě)之間還是互斥的,所以比較適合讀多寫(xiě)少的場(chǎng)景。

它的實(shí)現(xiàn)里面有 5 個(gè)方式:

func(rw*RWMutex)Lock()
func(rw*RWMutex)RLock()
func(rw*RWMutex)RLocker()Locker
func(rw*RWMutex)RUnlock()
func(rw*RWMutex)Unlock()

其中 Lock() 和 Unlock() 用于申請(qǐng)和釋放寫(xiě)鎖,RLock() 和 RUnlock() 用于申請(qǐng)和釋放讀鎖,RLocker() 用于返回一個(gè)實(shí)現(xiàn)了 Lock() 和 Unlock() 方法的 Locker 接口

實(shí)話說(shuō),平時(shí)這個(gè)用的真不多,主要是使用起來(lái)比較復(fù)雜,雖然在讀性能上面比Mutex要好一點(diǎn)。

4.sync.Map

這個(gè)類型印象中是后來(lái)加的,最早很多人使用互斥鎖來(lái)并發(fā)的操作 map,現(xiàn)在也還有人這么寫(xiě):

typeUserstruct{
mmap[string]string
lsync.Mutex
}

也就是一個(gè) map 配一把鎖的寫(xiě)法,可能是這種寫(xiě)法比較多,于是乎官方就在標(biāo)準(zhǔn)庫(kù)里面實(shí)現(xiàn)了一個(gè)sync.Map, 是一個(gè)自帶鎖的 map,使用起來(lái)方便很多,省心。

varmsync.Map

funcmain(){
m.Store("1",1)
m.Store("2",1)
m.Store("3",1)
m.Store(4,"5")//注意類型

load,ok:=m.Load("1")
ifok{
fmt.Printf("%v
",load)
}

load,ok=m.Load(4)
ifok{
fmt.Printf("%v
",load)
}
}

需要注意的一點(diǎn)是這個(gè) map 的 key 和 value 都是 interface{}類型,所以可以隨意放入任何類型的數(shù)據(jù),在使用的時(shí)候就需要做好斷言處理。

5.sync.Once

packagemain

import"sync"

varoncesync.Once

funcmain(){
doOnce()
}

funcdoOnce(){
once.Do(func(){
println("one")
})
}

執(zhí)行結(jié)果只打印了一個(gè) one,所以 sync.Once 的功能就是保證只執(zhí)行一次,也算是一種鎖,通常可以用于只能執(zhí)行一次的初始化操作,比如說(shuō)單例模式里面的懶漢模式可以用到。

6.sync.Cond

這個(gè)一般稱之為條件鎖,就是當(dāng)滿足某些條件下才起作用的鎖,啥個(gè)意思呢?舉個(gè)例子,當(dāng)我們執(zhí)行某個(gè)操作需要先獲取鎖,但是這個(gè)鎖必須是由某個(gè)條件觸發(fā)的,其中包含三種方式:

等待通知:wait, 阻塞當(dāng)前線程,直到收到該條件變量發(fā)來(lái)的通知

單發(fā)通知:signal, 讓該條件變量向至少一個(gè)正在等待它的通知的線程發(fā)送通知,表示共享數(shù)據(jù)的狀態(tài)已經(jīng)改變

廣播通知:broadcast, 讓條件變量給正在等待它的通知的所有線程都發(fā)送通知

下面看一個(gè)簡(jiǎn)單的例子:

packagemain
import(
"sync"
"time"
)

varcond=sync.NewCond(&sync.Mutex{})

funcmain(){
fori:=0;i10;i++{
gofunc(iint){
cond.L.Lock()
cond.Wait()//等待通知,阻塞當(dāng)前goroutine
println(i)
cond.L.Unlock()
}(i)
}

//確保所有協(xié)程啟動(dòng)完畢
time.Sleep(time.Second*1)

cond.Signal()

//確保結(jié)果有時(shí)間輸出
time.Sleep(time.Second*1)
}

開(kāi)始我們使用 for 循環(huán)啟動(dòng) 10 個(gè)協(xié)程,每個(gè)協(xié)程都在等待鎖,然后使用 signal 發(fā)送一個(gè)通知。

如果你多次運(yùn)行,你會(huì)發(fā)現(xiàn)打印的結(jié)果也是隨機(jī)從 0 到 9,說(shuō)明各個(gè)協(xié)程之間是競(jìng)爭(zhēng)的,鎖是起到作用的。如果把 singal 替換成 broadcast,則會(huì)打印所有結(jié)果。

講實(shí)話,我暫時(shí)也沒(méi)有發(fā)現(xiàn)有哪些應(yīng)用場(chǎng)景,感覺(jué)這個(gè)應(yīng)該適合需要非常精細(xì)的協(xié)程控制場(chǎng)景,大家先了解一下吧。

7.sync.WaitGroup

這個(gè)大多數(shù)人都用過(guò),一般用來(lái)控制協(xié)程執(zhí)行順序,大家都知道如果我們直接用 go 啟動(dòng)一個(gè)協(xié)程,比如下面這個(gè)寫(xiě)法:

gofunc(){
println("1")
}()

time.Sleep(time.Second*1)//睡眠1s

如果沒(méi)有后面的 sleep 操作,協(xié)程就得不到執(zhí)行,因?yàn)檎麄€(gè)函數(shù)結(jié)束了,主進(jìn)程都結(jié)束了協(xié)程哪有時(shí)間執(zhí)行,所以有時(shí)候?yàn)榱朔奖憧梢灾苯雍?jiǎn)單粗暴的睡眠幾秒,但是實(shí)際應(yīng)用中不可行。這時(shí)候就可以使用 waitGroup 解決這個(gè)問(wèn)題,舉個(gè)例子:

packagemain

import"sync"

varwgsync.WaitGroup

funcmain(){
fori:=0;i10;i++{
wg.Add(1)//計(jì)數(shù)+1
gofunc(){
println("1")
wg.Done()//計(jì)數(shù)-1,相當(dāng)于wg.add(-1)
}()
}
wg.Wait()//阻塞帶等待所有協(xié)程執(zhí)行完畢
}

8.sync.Pool

這是一個(gè)池子,但是卻是一個(gè)不怎么可靠的池子,sync.Pool 初衷是用來(lái)保存和復(fù)用臨時(shí)對(duì)象,以減少內(nèi)存分配,降低 CG 壓力。

說(shuō)它不可靠是指放進(jìn) Pool 中的對(duì)象,會(huì)在說(shuō)不準(zhǔn)什么時(shí)候被 GC 回收掉,所以如果事先 Put 進(jìn)去 100 個(gè)對(duì)象,下次 Get 的時(shí)候發(fā)現(xiàn) Pool 是空也是有可能的。

packagemain

import(
"fmt"
"sync"
)

typeUserstruct{
namestring
}

varpool=sync.Pool{
New:func()interface{}{
returnUser{
name:"defaultname",
}
},
}

funcmain(){
pool.Put(User{name:"name1"})
pool.Put(User{name:"name2"})

fmt.Printf("%v
",pool.Get())//{name1}
fmt.Printf("%v
",pool.Get())//{name2}
fmt.Printf("%v
",pool.Get())//{defaultname}池子已空,會(huì)返回New的結(jié)果
}

從輸出結(jié)果可以看到,Pool 就像是一個(gè)池子,我們放進(jìn)去什么東西,但不一定可以取出來(lái)(如果中間有 GC 的話就會(huì)被清空),如果池子空了,就會(huì)使用之前定義的 New 方法返回的結(jié)果。

為什么這個(gè)池子會(huì)放到 sync 包里面呢?那是因?yàn)樗幸粋€(gè)重要的特性就是協(xié)程安全的,所以其底層自然也用到鎖機(jī)制。

至于其應(yīng)用場(chǎng)景,知名的 Web 框架 Gin 里面就有用到,在處理用戶的每條請(qǐng)求時(shí)都會(huì)為當(dāng)前請(qǐng)求創(chuàng)建一個(gè)上下文環(huán)境 Context,用于存儲(chǔ)請(qǐng)求信息及相應(yīng)信息等。Context 滿足長(zhǎng)生命周期的特點(diǎn),且用戶請(qǐng)求也是屬于并發(fā)環(huán)境,所以對(duì)于線程安全的 Pool 非常適合用來(lái)維護(hù) Context 的臨時(shí)對(duì)象池。

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Web
    Web
    +關(guān)注

    關(guān)注

    2

    文章

    1254

    瀏覽量

    69204
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4260

    瀏覽量

    62233
  • go語(yǔ)言
    +關(guān)注

    關(guān)注

    1

    文章

    157

    瀏覽量

    9004

原文標(biāo)題:淺談 Golang 鎖的應(yīng)用: sync包

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    go語(yǔ)言如何解決并發(fā)問(wèn)題

    GO快很多?,F(xiàn)在工作也還是有一些老項(xiàng)目在使用PHP,但21年之后的新項(xiàng)目基本上就都是GO了。那為什么PHP那么香,還要轉(zhuǎn)戰(zhàn)使用GO呢,下
    的頭像 發(fā)表于 10-23 13:38 ?38次閱讀
    <b class='flag-5'>go</b><b class='flag-5'>語(yǔ)言</b>如何解決并發(fā)問(wèn)題

    三十分鐘入門基礎(chǔ)Go Java小子版

    前言 Go語(yǔ)言定義 Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開(kāi)發(fā)的一種靜態(tài)、強(qiáng)類型、編譯型語(yǔ)言
    的頭像 發(fā)表于 08-12 14:32 ?636次閱讀
    三十分鐘入門基礎(chǔ)<b class='flag-5'>Go</b> Java小子版

    自旋和互斥的使用場(chǎng)景是什么

    自旋和互斥是兩種常見(jiàn)的同步機(jī)制,它們?cè)诙嗑€程編程中被廣泛使用。在本文中,我們將介紹自旋和互斥的使用場(chǎng)景,以及它們?cè)诓煌?/div>
    的頭像 發(fā)表于 07-10 10:05 ?731次閱讀

    請(qǐng)問(wèn)STVP+COSMIC環(huán)境go to definition怎么?

    STVP+COSMIC環(huán)境go to definition怎么? 我現(xiàn)在go to definition在一個(gè)宏定義的時(shí)候有效果,但是函數(shù)什么的沒(méi)用,是怎么回事呢,是不是工程里面
    發(fā)表于 05-11 06:11

    關(guān)于go接口類型的表示方法

    go是一個(gè)靜態(tài)性語(yǔ)言,每個(gè)變量都有靜態(tài)的類型,因此每個(gè)變量在編譯階段中有明確的變量類型,比如像:int、float32、MyType。
    的頭像 發(fā)表于 04-28 10:13 ?297次閱讀

    fpga的是什么編程語(yǔ)言 fpga什么語(yǔ)言開(kāi)發(fā)

    fpga的是什么編程語(yǔ)言 FPGA(現(xiàn)場(chǎng)可編程邏輯門陣列)主要使用的編程語(yǔ)言是硬件描述語(yǔ)言(HDL)。在眾多的HDL,Verilog H
    的頭像 發(fā)表于 03-14 17:09 ?3131次閱讀

    使用go語(yǔ)言實(shí)現(xiàn)一個(gè)grpc攔截器

    在開(kāi)發(fā)grpc服務(wù)時(shí),我們經(jīng)常會(huì)遇到一些通用的需求,比如:日志、鏈路追蹤、鑒權(quán)等。這些需求可以通過(guò)grpc攔截器來(lái)實(shí)現(xiàn)。本文使用go語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè) grpc一元模式(Unary)攔截器,上報(bào)鏈路追蹤信息。
    的頭像 發(fā)表于 12-18 10:13 ?584次閱讀
    使用<b class='flag-5'>go</b><b class='flag-5'>語(yǔ)言</b>實(shí)現(xiàn)一個(gè)grpc攔截器

    Go編程語(yǔ)言-你應(yīng)該知道的一切

    Go 編程語(yǔ)言的故事始于 Google,當(dāng)時(shí)三位工程師 Robert Griesemer、Rob Pike 和 Ken Thompson 對(duì) C++ 的復(fù)雜性以及缺乏提供高效編譯和執(zhí)行的簡(jiǎn)單語(yǔ)言感到厭倦。
    的頭像 發(fā)表于 12-11 17:37 ?564次閱讀

    redis分布式的應(yīng)用場(chǎng)景有哪些

    Redis分布式是一種基于Redis實(shí)現(xiàn)的分布式機(jī)制,可以在分布式環(huán)境確保資源的獨(dú)占性,避免并發(fā)訪問(wèn)時(shí)的數(shù)據(jù)爭(zhēng)問(wèn)題。下面將詳細(xì)介紹Redis分布式
    的頭像 發(fā)表于 12-04 11:21 ?1319次閱讀

    AD9910的SYNC_CLK沒(méi)有輸出是為什么?

    我想問(wèn)一,我的是晶體驅(qū)動(dòng)方式,現(xiàn)在沒(méi)有配置的情況,REFCLK_OUT有25M頻率輸出,但是SYNC_CLK沒(méi)有輸出,一直為低。這是什么原因?
    發(fā)表于 11-27 07:14

    Linux場(chǎng)景數(shù)據(jù)是如何在協(xié)議層傳輸?shù)?/a>

    所有互聯(lián)網(wǎng)服務(wù),均依賴于TCP/IP協(xié)議棧。懂得數(shù)據(jù)是如何在協(xié)議棧傳輸?shù)?,將?huì)幫助你提升互聯(lián)網(wǎng)程序的性能和解決TCP相關(guān)問(wèn)題的能力。 我們講述在Linux場(chǎng)景數(shù)據(jù)是如何在協(xié)議層傳輸?shù)摹?1、發(fā)送
    的頭像 發(fā)表于 11-11 11:33 ?1026次閱讀
    Linux<b class='flag-5'>場(chǎng)景</b><b class='flag-5'>下</b>數(shù)據(jù)<b class='flag-5'>包</b>是如何在協(xié)議層傳輸?shù)? />    </a>
</div>                            <div   id=

    無(wú)隊(duì)列的潛在優(yōu)勢(shì)

    ; return old_reg_val; } 它將reg的值與oldval的值進(jìn)行對(duì)比,若相同則將reg賦新值。注意以上操作是原子操作。大部分語(yǔ)言都有提供CAS支持,不過(guò)函數(shù)原型可能有些微的不同,許多語(yǔ)言(包括go
    的頭像 發(fā)表于 11-09 09:23 ?505次閱讀
    無(wú)<b class='flag-5'>鎖</b>隊(duì)列的潛在優(yōu)勢(shì)

    Go語(yǔ)言比Python強(qiáng)多少

    1.都說(shuō)Go語(yǔ)言性能非常強(qiáng)大,那么到底比Python強(qiáng)多少? 為了比較Go語(yǔ)言和Python語(yǔ)言在單線程性能上的差距,我們可以做一個(gè)簡(jiǎn)單實(shí)驗(yàn)
    的頭像 發(fā)表于 11-02 14:05 ?483次閱讀
    <b class='flag-5'>Go</b><b class='flag-5'>語(yǔ)言</b>比Python強(qiáng)多少

    如何讓Python和Go互相調(diào)度

    我們?cè)?jīng)研究過(guò)如何讓Python和Go互相調(diào)度,當(dāng)時(shí)發(fā)現(xiàn),將Go語(yǔ)言寫(xiě)的模塊打包成動(dòng)態(tài)鏈接庫(kù),就能在Python中進(jìn)行調(diào)度: 優(yōu)劣互補(bǔ)! Python+Go結(jié)合開(kāi)發(fā)的探討
    的頭像 發(fā)表于 11-02 11:24 ?513次閱讀
    如何讓Python和<b class='flag-5'>Go</b>互相調(diào)度

    Go在單線程計(jì)算性能上的優(yōu)勢(shì)

    ,將計(jì)算和保存的過(guò)程保存在本地的redis緩存,然后使用Celery來(lái)調(diào)度這些任務(wù)。 問(wèn)題在于,從這些網(wǎng)址獲取數(shù)據(jù)的步驟,寫(xiě)在Go Worker里是否合適?Go進(jìn)行網(wǎng)絡(luò)請(qǐng)求是否比P
    的頭像 發(fā)表于 11-02 11:16 ?417次閱讀
    <b class='flag-5'>Go</b>在單線程計(jì)算性能上的優(yōu)勢(shì)