從三體質(zhì)子鎖定地球科技 簡(jiǎn)析Golang的并發(fā)

從三體質(zhì)子鎖定地球科技 簡(jiǎn)析Golang的并發(fā)

好吧鹿榜,我承認(rèn)這個(gè)標(biāo)題是騙你進(jìn)來的命爬,那么來都來了施敢,看完再走吧周荐。

——

通常情況下,我們都會(huì)覺得golang有著不錯(cuò)的性能僵娃。那么這個(gè)不錯(cuò)的性能是如何得出的呢概作?我覺得大概有以下幾點(diǎn)

  • 靜態(tài)語言VS動(dòng)態(tài)語言
    靜態(tài)語言通常有著比解釋型語言更好的性能. 靜態(tài)語言需要預(yù)先編譯成二進(jìn)制機(jī)器語言,執(zhí)行效率自然比解釋型語言的解釋器邊解釋邊執(zhí)行效率要高出不少.
    所以默怨,單從執(zhí)行效率上看仆嗦,C/C++/C#/Java/Golang 等靜態(tài)要比 Python/Javascript/Ruby等 動(dòng)態(tài)語言要高出不少

  • GC(Garbage Collection)
    相比Java的虛擬機(jī)JVM或C# 的.NET Framework 提供的垃圾回收機(jī)制,Golang有著更高的效率.
    詳細(xì)上先壕,Golang的GC咱沒做過仔細(xì)研究,.NET 的GC有著引用計(jì)數(shù)以及三代的垃圾處理機(jī)制谆甜,實(shí)際上垃僚,微軟在.net core里也做了一定的優(yōu)化,但總歸來說规辱,Golang的GC更加的輕量谆棺,執(zhí)行效率也更高(沒有虛擬機(jī)呀).

  • 并發(fā)VS并行
    并發(fā):同一時(shí)刻,通過調(diào)度罕袋,來回切換交替運(yùn)行多個(gè)任務(wù)改淑,給人的感覺是同時(shí)運(yùn)行的
    并行:同一時(shí)刻,多個(gè)任務(wù)同時(shí)在運(yùn)行.

回到標(biāo)題浴讯,在科幻小說<<三體>>中朵夏,三體星人通過發(fā)送到地球的一個(gè)高維展開過的質(zhì)子就能攪亂地球的所有粒子對(duì)撞機(jī)的規(guī)律, 那么,三體的質(zhì)子應(yīng)該是并發(fā)來處理的而不是并行的來執(zhí)行干擾工作.
并發(fā)通過切換CPU運(yùn)行時(shí)間片榆纽,能達(dá)到非常高的執(zhí)行效率仰猖。尤其是在IO密集的計(jì)算中.

Golang 使用goroutine 來支持并發(fā), goroutine說白了其實(shí)就是協(xié)程捏肢,但是它比線程輕量。線程的建立需要較多的資源消耗饥侵,但是, 執(zhí)行g(shù)oroutine只需極少的棧內(nèi)存鸵赫。


Golang中的并發(fā)

雖然并發(fā)并非golang所特有, 比如python就有對(duì)協(xié)程的支持躏升。但是就便捷性上來講辩棒,Golang從語言層面就支持了并發(fā),使用起來也更加方便.

goroutine通過在函數(shù)前加 go關(guān)鍵字實(shí)現(xiàn), 一個(gè)官方的例子.

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(time.Millisecond * 10)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}

執(zhí)行結(jié)果:
hello
world
hello
world
world
hello
world
hello
world
hello

Channel

goroutine的函數(shù)運(yùn)行在相同的地址空間膨疏,那么就必須做好內(nèi)存同步工作一睁。相比其它語言的多線程同步鎖,golang 使用channel 來進(jìn)行數(shù)據(jù)通信成肘, 顯得非常的優(yōu)秀和高效卖局。 channel 可以發(fā)送也可以接受channel 類型的值. 我們可以使用make來定義一個(gè)channel.

var ch_i = make(chan int)
var ch_s = make(chan string)
var ch_st = make(chan struct{})

舉個(gè)栗子。
我們要計(jì)算一個(gè)數(shù)組所有元素的累加和双霍, 我們可以把相應(yīng)的數(shù)組拆成若干個(gè)goroutine并發(fā)執(zhí)行.

package main

import "fmt"

func sum(a []int, c chan int) {
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total
}

func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    go sum(a[:2], c)
    go sum(a[2:4], c)
    go sum(a[4:], c)
    x, y, z := <-c, <-c, <-c

    fmt.Println(x, y, z, x+y+z)
}

執(zhí)行結(jié)果:
4 -1 9 12
三個(gè)協(xié)程并發(fā)計(jì)算結(jié)果并通過channel 來傳遞數(shù)據(jù).
通過 c <- total砚偶, 把計(jì)算結(jié)果傳遞給channel, 通過 x, y, z := <-c, <-c, <-c 來接受channel的值.

帶緩存的channel

默認(rèn)的channel是不帶緩存的洒闸,但我們也可以創(chuàng)建帶緩存的channel. 在channel創(chuàng)建的時(shí)候可以指定緩存大小染坯。
在緩存大小范圍內(nèi),就可以一直往channel里塞丘逸。直到塞滿单鹿,阻塞。再直到有人從channel取出深纲,釋放緩存仲锄。

舉個(gè)栗子。
我們定義一個(gè)帶緩存的channel湃鹊,用來存儲(chǔ)斐波那契數(shù)組.

package main

import "fmt"

func fibonacci(n int, c chan int) {
    x, y := 1, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
}

func main() {
    c := make(chan int, 5)
    go fibonacci(cap(c), c)
    x, y, z, a, b := <-c, <-c, <-c, <-c, <-c
    fmt.Println(x, y, z, a, b)
}

運(yùn)行結(jié)果:
1 1 2 3 5

遍歷/關(guān)閉 channel

上面的例子略顯丑儒喊,我們可以通過range 函數(shù)來遍歷緩存里的值.

package main

import "fmt"

func fibonacci(n int, c chan int) {
    x, y := 1, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
}

func main() {
    c := make(chan int, 10)
    go fibonacci(cap(c), c)
    for i := range c {
        fmt.Println(i)
    }
}

運(yùn)行結(jié)果:
1
1
2
3
5
8
13
21
34
55
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
C:/Users/trump/go/src/github.com/goroutine-test/main.go:16 +0xb9

系統(tǒng)報(bào)了一個(gè)錯(cuò)誤,意思是說所有的goroutines 都沒了币呵。原因就是怀愧,range 函數(shù)在channel 沒有關(guān)閉的時(shí)候會(huì)一直運(yùn)行,10個(gè)讀完了以后余赢,沒有新的數(shù)值進(jìn)來芯义,它就死了。

解決辦法:
在fibonacci函數(shù)中關(guān)閉通道妻柒。

package main

import "fmt"

func fibonacci(n int, c chan int) {
    x, y := 1, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func main() {
    c := make(chan int, 10)
    go fibonacci(cap(c), c)
    for i := range c {
        fmt.Println(i)
    }
}

總結(jié)

以上就是個(gè)人對(duì)Golang 并發(fā)的一些粗淺理解扛拨。
雖然您可能被騙了,但如果文章對(duì)你有所幫助蛤奢,也是值了鬼癣。謝謝陶贼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市待秃,隨后出現(xiàn)的幾起案子拜秧,更是在濱河造成了極大的恐慌,老刑警劉巖章郁,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枉氮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡暖庄,警方通過查閱死者的電腦和手機(jī)聊替,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來培廓,“玉大人惹悄,你說我怎么就攤上這事〖缒疲” “怎么了泣港?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)价匠。 經(jīng)常有香客問我当纱,道長(zhǎng),這世上最難降的妖魔是什么踩窖? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任坡氯,我火速辦了婚禮,結(jié)果婚禮上洋腮,老公的妹妹穿的比我還像新娘箫柳。我一直安慰自己,他們只是感情好啥供,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布滞时。 她就那樣靜靜地躺著,像睡著了一般滤灯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上曼玩,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天鳞骤,我揣著相機(jī)與錄音,去河邊找鬼黍判。 笑死豫尽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顷帖。 我是一名探鬼主播美旧,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼渤滞,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了榴嗅?” 一聲冷哼從身側(cè)響起妄呕,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗽测,沒想到半個(gè)月后绪励,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唠粥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年疏魏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晤愧。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡大莫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出官份,到底是詐尸還是另有隱情只厘,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布贯吓,位于F島的核電站懈凹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏悄谐。R本人自食惡果不足惜介评,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爬舰。 院中可真熱鬧们陆,春花似錦、人聲如沸情屹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垃你。三九已至椅文,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惜颇,已是汗流浹背皆刺。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凌摄,地道東北人羡蛾。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锨亏,于是被迫代替她去往敵國(guó)和親痴怨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忙干,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359