20-Go語言并發(fā)編程

并發(fā)編程基本概念

  • 學(xué)習(xí)并發(fā)編程之前我們需要腦補(bǔ)幾個(gè)基礎(chǔ)知識和思考一個(gè)問題
    • 什么是串行?
    • 什么是并行?
    • 什么是并發(fā)?
    • 什么是程序?
    • 什么是進(jìn)程?
    • 什么是線程?
    • 什么是協(xié)程?

  • 什么是串行?

    • 串行就是按順序執(zhí)行, 就好比銀行只有1個(gè)窗口, 有3個(gè)人要辦事, 那么必須排隊(duì), 只有前面的人辦完走人, 才能輪到你
    • 在計(jì)算機(jī)中, 同一時(shí)刻, 只能有一條指令, 在一個(gè)CPU上執(zhí)行, 后面的指令必須等到前面指令執(zhí)行完才能執(zhí)行, 就是串行
  • 什么是并行?

    • 并行就是同時(shí)執(zhí)行, 就好比銀行有3個(gè)窗口, 有3個(gè)人要辦事, 只需要到空窗口即可立即辦事.
    • 在計(jì)算機(jī)中, 同一時(shí)刻, 有多條指令, 在多個(gè)CPU上執(zhí)行, 就是并行
    • 從以上分析不難看出, 并行的速度優(yōu)于串行
  • 什么是并發(fā)?

    • 并發(fā)是偽并行, 就好比銀行只有1個(gè)窗口, 有3個(gè)人要辦事, 那么沒輪到后面的人時(shí), 后面的人可以用拖鞋先排隊(duì), 去吃個(gè)早餐,買個(gè)東西啥的, 感覺差不多要到自己時(shí)再回來辦事
    • 在計(jì)算機(jī)中, 同一時(shí)刻, 只能有一條指令, 在一個(gè)CPU上執(zhí)行, 但是CPU會快速的在多條指令之間輪詢執(zhí)行就是并發(fā)
    • 并行和并發(fā)的區(qū)別就好比古代的三妻四妾(名正言順, 光明正大)和現(xiàn)代三妻四妾(抽空幽會, 小三小四)
  • 總結(jié):

    • 多線程程序在單核上運(yùn)行, 就是并發(fā)
    • 多線程程序在多核上運(yùn)行,就是并行

  • 什么是程序?
    • 程序是指編譯之后存儲在磁盤上的一個(gè)二進(jìn)制文件, 會占用磁盤空間, 但不會占用系統(tǒng)資源
  • 什么是進(jìn)程?
    • 進(jìn)程是指程序在操作系統(tǒng)中的一次執(zhí)行過程, 是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位
    • 例如:
      • 啟動(dòng)記事本這個(gè)程序, 在系統(tǒng)中就會創(chuàng)建一個(gè)記事本進(jìn)程
      • 再次啟動(dòng)記事本這個(gè)程序, 又會在系統(tǒng)中創(chuàng)建一個(gè)記事本進(jìn)程
    • 程序和進(jìn)程的關(guān)系就好比劇本和演出的關(guān)系
      • 劇本對應(yīng)程序, 演出對應(yīng)進(jìn)程. 同一個(gè)劇本可以在多個(gè)舞臺同時(shí)演出互不影響, 同一個(gè)程序可以在系統(tǒng)中開啟多個(gè)進(jìn)程互不影響
    • 所以程序和進(jìn)程的關(guān)系是1:N, 所以多個(gè)進(jìn)程的空間是獨(dú)立的
  • 什么是線程?
    • 線程是指進(jìn)程中的一個(gè)執(zhí)行實(shí)例, 是程序執(zhí)行的最小單元, 它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位
    • 一個(gè)進(jìn)程中至少有一個(gè)線程, 這個(gè)線程我們稱之為主線程
    • 一個(gè)進(jìn)程中除了主線程以外, 我們還可以創(chuàng)建和銷毀多個(gè)線程
    • 例如:
      • 啟動(dòng)迅雷這個(gè)程序, 系統(tǒng)會創(chuàng)建一個(gè)迅雷進(jìn)程, 并且默認(rèn)會有一個(gè)主線程, 用于執(zhí)行迅雷默認(rèn)的業(yè)務(wù)邏輯
      • 當(dāng)我們利用迅雷下載多個(gè)任務(wù)的時(shí)候, 會發(fā)現(xiàn)多個(gè)任務(wù)都在同時(shí)下載, 此時(shí)為了能夠同時(shí)執(zhí)行下載操作, 迅雷就會創(chuàng)建多個(gè)線程, 將不同的下載任務(wù)放到不同的線程中執(zhí)行
  • 什么是協(xié)程?
    • 協(xié)程是一種用戶態(tài)的輕量級線程币旧,又稱微線程甫贯,英文名Coroutine
    • 與傳統(tǒng)的系統(tǒng)級別進(jìn)程和線程相比, 協(xié)程最大的優(yōu)勢在于"輕量級". 可以輕松創(chuàng)建上萬個(gè)不會導(dǎo)致系統(tǒng)資源衰竭. 而線程和進(jìn)程通常很難超過1萬個(gè).這也是協(xié)程稱之為"輕量級線程"的原因
    • 一個(gè)線程中可以有任意多個(gè)協(xié)程, 但某一時(shí)刻只能有一個(gè)協(xié)程在運(yùn)行, 多個(gè)協(xié)程分享所在線程分配到的計(jì)算機(jī)資源
    • 在協(xié)程中, 調(diào)用一個(gè)任務(wù)就像調(diào)用一個(gè)函數(shù)一樣, 消耗系統(tǒng)資源極少, 但能達(dá)到進(jìn)程、線程相同的并發(fā)效果

Go并發(fā)

  • Go在語言級別支持協(xié)程(多數(shù)語言在語法層面并不直接支持協(xié)程), 叫做goroutine.

  • 人們把Go語言稱之為21世紀(jì)的C語言. 第一是因?yàn)镚o語言設(shè)計(jì)簡單, 第二是因?yàn)?1世紀(jì)最重要的就是并行程序設(shè)計(jì).而Go從語言層面就支持并發(fā)和并行

  • Go并發(fā)小案例

package main

import (
    "fmt"
    "time"
)

func sing()  {
    for i:=0; i< 10; i++{
        fmt.Println("我在唱歌")
        time.Sleep(time.Millisecond)
    }
}
func dance() {
    for i:=0; i< 10; i++{
        fmt.Println("我在跳舞---")
        time.Sleep(time.Millisecond)
    }
}

func main() {
    // 串行: 必須先唱完歌才能跳舞
    //sing()
    //dance()

    // 并行: 可以邊唱歌, 邊跳舞
    // 注意點(diǎn): 主線程不能死, 否則程序就退出了
    go sing() // 開啟一個(gè)協(xié)程
    go dance() // 開啟一個(gè)協(xié)程
    for{
        ;
    }
}
  • runtime包中常用的函數(shù)
    • Gosched:使當(dāng)前go程放棄處理器荒叼,以讓其它go程運(yùn)行
      package main
      import (
          "fmt"
          "runtime"
      )
      
      func sing()  {
          for i:=0; i< 10; i++{
              fmt.Println("我在唱歌")
              // Gosched使當(dāng)前go程放棄處理器染厅,以讓其它go程運(yùn)行泽谨。
              // 它不會掛起當(dāng)前go程兔毒,因此當(dāng)前go程未來會恢復(fù)執(zhí)行
              runtime.Gosched()
          }
      }
      func dance() {
          for i:=0; i< 10; i++{
              fmt.Println("我在跳舞---")
              runtime.Gosched()
          }
      }
      
      func main() {
      
          go sing()
          go dance()
          for{
              ;
          }
      }
    
    • Goexit: 終止調(diào)用它的go程, 其它go程不會受影響
      package main
      import (
          "fmt"
          "runtime"
      )
      
      func main() {
          go func() {
              fmt.Println("123")
              // 退出當(dāng)前協(xié)程
              //runtime.Goexit()
              // 退出當(dāng)前函數(shù)
              //return
              test()
              fmt.Println("456")
          }()
          for{
              ;
          }
      }
      
      func test()  {
          fmt.Println("abc")
          // 只會結(jié)束當(dāng)前函數(shù), 協(xié)程中的其它代碼會繼續(xù)執(zhí)行
          //return
          // 會結(jié)束整個(gè)協(xié)程, Goexit之后整個(gè)協(xié)程中的其它代碼不會執(zhí)行
          runtime.Goexit()
          fmt.Println("def")
      }
    
    • NumCPU: 返回本地機(jī)器的邏輯CPU個(gè)數(shù)
      package main
      import (
          "fmt"
          "runtime"
      )
      func main() {
          num := runtime.NumCPU()
          fmt.Println(num)
      }
    
    • GOMAXPROCS: 設(shè)置可同時(shí)執(zhí)行的最大CPU數(shù)咖楣,并返回先前的設(shè)置
      • Go語言1.8之前, 需要我們手動(dòng)設(shè)置
      • Go語言1.8之后, 不需要我們手動(dòng)設(shè)置
      func main() {
          // 獲取帶來了CPU個(gè)數(shù)
          num := runtime.NumCPU()
          // 設(shè)置同時(shí)使用CPU個(gè)數(shù)
          runtime.GOMAXPROCS(num)
      }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末等龙,一起剝皮案震驚了整個(gè)濱河市处渣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛛砰,老刑警劉巖罐栈,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異泥畅,居然都是意外死亡荠诬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門位仁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柑贞,“玉大人,你說我怎么就攤上這事聂抢【唬” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵琳疏,是天一觀的道長有决。 經(jīng)常有香客問我,道長空盼,這世上最難降的妖魔是什么书幕? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮揽趾,結(jié)果婚禮上台汇,老公的妹妹穿的比我還像新娘。我一直安慰自己但骨,他們只是感情好励七,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奔缠,像睡著了一般掠抬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上校哎,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天两波,我揣著相機(jī)與錄音瞳步,去河邊找鬼。 笑死腰奋,一個(gè)胖子當(dāng)著我的面吹牛单起,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劣坊,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼嘀倒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了局冰?” 一聲冷哼從身側(cè)響起测蘑,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎康二,沒想到半個(gè)月后碳胳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沫勿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年挨约,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片产雹。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诫惭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洽故,到底是詐尸還是另有隱情贝攒,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布时甚,位于F島的核電站隘弊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荒适。R本人自食惡果不足惜梨熙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刀诬。 院中可真熱鬧咽扇,春花似錦、人聲如沸陕壹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糠馆。三九已至嘶伟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間又碌,已是汗流浹背九昧。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工绊袋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铸鹰。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓癌别,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹋笼。 傳聞我的和親對象是個(gè)殘疾皇子展姐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容