并發(fā)編程

介紹

線程:輕量級(jí)進(jìn)程
攜程:輕量級(jí)線程

并發(fā)

協(xié)程

mac活動(dòng)監(jiān)視器=任務(wù)管理器

線程:進(jìn)程中的執(zhí)行路徑

package main

import "fmt"

//9
func main() {
    /*
    一個(gè)goroutine打印數(shù)字缎岗,另外一個(gè)goroutine打印字母耳幢,觀察運(yùn)行結(jié)果
    */
    //1. 先創(chuàng)建并啟動(dòng)子goroutine默穴,執(zhí)行printNum()
    go printNum()

    //2. main打印字母
    for i:=1;i<=100;i++ {
        fmt.Printf("\t主goroutine打印字母:A %d\n",i)
    }

    fmt.Println("main over...")

}

func printNum(){
    for i:=1;i<=100;i++ {
        fmt.Printf("子goroutine打印數(shù)字:%d\n",i)
    }
}

主goroutine結(jié)束直颅,程序就結(jié)束了,不管子goroutine讹蘑,可以用管道通信

與函數(shù)不同末盔,所以寫(xiě)了返回值也沒(méi)有用

啟動(dòng)多個(gè)goroutine

并發(fā)模型

runtime包

類(lèi)似與虛擬機(jī),管理內(nèi)存

package main

import (
    "fmt"
    "runtime"
    "time"
)

//10
func main() {
    //獲取goroot目錄
    fmt.Println("GOROOT---->",runtime.GOROOT()) //GOROOT----> /usr/local/go

    //獲取操作系統(tǒng)
    fmt.Println("os/platform---->",runtime.GOOS) //os/platform----> darwin,mac系統(tǒng)

    //獲取邏輯cpu的數(shù)量
    fmt.Println("邏輯CPU的數(shù)量---->",runtime.NumCPU()) //邏輯CPU的數(shù)量----> 8

    //設(shè)置cpu數(shù)量座慰,不要亂寫(xiě)陨舱,寫(xiě)當(dāng)前邏輯cpu數(shù)量就行,最好寫(xiě)在init函數(shù)
    //n := runtime.GOMAXPROCS(16)
    //fmt.Println(n)

    //gosched讓出當(dāng)前時(shí)間片版仔,讓別的goroutine先執(zhí)行
    go func(){
        for i := 0; i < 5; i++ {
            fmt.Println("goroutine...")
        }
    }()

    for i := 0; i < 5; i++ {
        //讓出時(shí)間片游盲,先讓別的goroutine執(zhí)行
        runtime.Gosched()
        fmt.Println("main...")
    }

    //創(chuàng)建goroutine
    go func() {
        fmt.Println("goroutine開(kāi)始")
        //調(diào)用fun
        fun()
        fmt.Println("goroutine結(jié)束")
    }()

    //睡一會(huì)
    time.Sleep(3 * time.Second)


}

func fun(){
    defer fmt.Println("defer...")
    // return //終止函數(shù)
    runtime.Goexit() //終止當(dāng)前的goroutine
    fmt.Println("fun函數(shù)")
}

臨界資源的安全問(wèn)題

package main

import (
    "fmt"
    "time"
)

//11
func main() {
    /*
    臨界資源
    */
    a := 1
    go func() {
        a = 2
        fmt.Println("goroutine中a:",a)
    }()

    a = 3
    time.Sleep(1)
    fmt.Println("main goroutine...",a)

}
package main

import (
    "fmt"
    "math/rand"
    "time"
)

//11
func main() {
    /*
    臨界資源
    */
    a := 1
    go func() {
        a = 2
        fmt.Println("goroutine中a:",a)
    }()

    a = 3
    time.Sleep(1)
    fmt.Println("main goroutine...",a)

    /*
    4個(gè)goroutine,模擬4個(gè)售票口
    */
    go saleTickets("售票口1")
    go saleTickets("售票口2")
    go saleTickets("售票口3")
    go saleTickets("售票口4")

    time.Sleep(5 * time.Second)

}

//全局變量
var ticket = 10

func saleTickets(name string) {
    for{
        if ticket > 0 {
            rand.Seed(time.Now().UnixNano())
            time.Sleep(time.Duration(rand.Intn(1000))*time.Millisecond)
            fmt.Println(name,"售出",ticket)
            ticket--
        }else {
            fmt.Println(name,"售罄蛮粮,沒(méi)有票了益缎。。")
            break
        }
    }
}

不鼓勵(lì)通過(guò)共享內(nèi)存通信然想,鼓勵(lì)通過(guò)通信來(lái)共享內(nèi)存

channel

sync包下的WaitGroup同步等待組

package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup //創(chuàng)建同步等待組的對(duì)象

//11
func main() {
    /*
        waitgroup:同步等待組
            Add()链峭,設(shè)置等待組中要執(zhí)行的子 goroutine 的數(shù)量

            Wait(),讓主goroutine等待
    */

    wg.Add(2)

    go fun1()
    go fun2()

    //無(wú)輸出

    fmt.Println("main進(jìn)入阻塞又沾,等待wg的子groutine結(jié)束")
    wg.Wait()
    fmt.Println("main阻塞解除")

}

func fun1(){
    for i := 1; i < 10; i++ {
        fmt.Println("fun1打印 a", i)
    }

    wg.Done() //給wg等待組count數(shù)值減1 == add(-1)
}

func fun2(){
    defer wg.Done()
    for i := 1; i < 10; i++ {
        fmt.Println("\tfun2打印 b", i)
    }
}

如果沒(méi)有wg.Done()

如果是1,隨便抓一個(gè)

互斥鎖

互斥鎖熙卡、讀寫(xiě)鎖

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

var wg sync.WaitGroup

//13
func main() {

    /*
        4個(gè)goroutine杖刷,模擬4個(gè)售票口
    */
    wg.Add(4)
    go saleTickets2("售票口1")
    go saleTickets2("售票口2")
    go saleTickets2("售票口3")
    go saleTickets2("售票口4")

    wg.Wait()
    fmt.Println("main over")

}

//全局變量
var ticket = 10

var mutex sync.Mutex //創(chuàng)建鎖

func saleTickets2(name string) {
    rand.Seed(time.Now().UnixNano())
    defer wg.Done()
    for{
        //上鎖
        mutex.Lock()
        if ticket > 0 {
            time.Sleep(time.Duration(rand.Intn(1000))*time.Millisecond)
            fmt.Println(name,"售出",ticket)
            ticket--
        }else {
            mutex.Unlock() //條件不滿足也要解鎖
            fmt.Println(name,"售罄,沒(méi)有票了驳癌。滑燃。")
            break
        }
        //解鎖
        mutex.Unlock()
    }
}

建議使用defer語(yǔ)句解鎖

讀寫(xiě)鎖

package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

var rwMutex *sync.RWMutex

//14
func main() {
    /*
    讀寫(xiě)鎖
    */
    rwMutex = new(sync.RWMutex)

    //wg.Add(2)
    //
    ////讀操作可以同時(shí)進(jìn)行
    //go readData(1)
    //go readData(2)

    wg.Add(3)
    go writeData(1)
    go readData(2)
    go writeData(3)

    wg.Wait()
    fmt.Println("main over")

}

func writeData(i int){
    defer wg.Done()

    fmt.Println(i,"開(kāi)始寫(xiě):write start。颓鲜。")

    rwMutex.Lock() //讀操作上鎖
    fmt.Println(i,"正在寫(xiě)")
    time.Sleep(1 * time.Second)
    rwMutex.Unlock() //讀操作解鎖
    fmt.Println(i,"寫(xiě)結(jié)束:write over")
}

func readData(i int){
    defer wg.Done()

    fmt.Println(i,"開(kāi)始讀:read start表窘。。")

    rwMutex.RLock() //讀操作上鎖
    fmt.Println(i,"正在讀取")
    time.Sleep(1 * time.Second)
    rwMutex.RUnlock() //讀操作解鎖
    fmt.Println(i,"讀結(jié)束:read over")

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甜滨,一起剝皮案震驚了整個(gè)濱河市乐严,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衣摩,老刑警劉巖昂验,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡既琴,警方通過(guò)查閱死者的電腦和手機(jī)占婉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甫恩,“玉大人逆济,你說(shuō)我怎么就攤上這事』腔” “怎么了奖慌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滞磺。 經(jīng)常有香客問(wèn)我升薯,道長(zhǎng),這世上最難降的妖魔是什么击困? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任涎劈,我火速辦了婚禮,結(jié)果婚禮上阅茶,老公的妹妹穿的比我還像新娘蛛枚。我一直安慰自己,他們只是感情好脸哀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蹦浦。 她就那樣靜靜地躺著,像睡著了一般撞蜂。 火紅的嫁衣襯著肌膚如雪盲镶。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天蝌诡,我揣著相機(jī)與錄音溉贿,去河邊找鬼。 笑死浦旱,一個(gè)胖子當(dāng)著我的面吹牛宇色,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颁湖,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宣蠕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了甥捺?” 一聲冷哼從身側(cè)響起抢蚀,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镰禾,沒(méi)想到半個(gè)月后思币,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鹿响,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年谷饿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惶我。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡博投,死狀恐怖蚜印,靈堂內(nèi)的尸體忽然破棺而出仅乓,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布集嵌,位于F島的核電站州泊,受9級(jí)特大地震影響冶共,放射性物質(zhì)發(fā)生泄漏蚀之。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一翅睛、第九天 我趴在偏房一處隱蔽的房頂上張望声搁。 院中可真熱鬧,春花似錦捕发、人聲如沸疏旨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)檐涝。三九已至,卻和暖如春法挨,著一層夾襖步出監(jiān)牢的瞬間谁榜,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工凡纳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惰爬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓惫企,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親陵叽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狞尔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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

  • 必備的理論基礎(chǔ) 1.操作系統(tǒng)作用: 隱藏丑陋復(fù)雜的硬件接口,提供良好的抽象接口巩掺。 管理調(diào)度進(jìn)程偏序,并將多個(gè)進(jìn)程對(duì)硬件...
    drfung閱讀 3,541評(píng)論 0 5
  • 概述 簡(jiǎn)而言之,所謂并發(fā)編程是指在一臺(tái)處理器上“同時(shí)”處理多個(gè)任務(wù)胖替。 隨著硬件的發(fā)展研儒,并發(fā)程序變得越來(lái)越重要豫缨。We...
    泡泡龍吐泡泡閱讀 7,910評(píng)論 1 12
  • Go 并發(fā)編程 選擇 Go 編程的原因可能是看中它簡(jiǎn)單且強(qiáng)大,那么你其實(shí)可以選擇C語(yǔ)言端朵;除此之外好芭,我看中 Go 的...
    PRE_ZHY閱讀 889評(píng)論 1 6
  • 參考《快學(xué) Go 語(yǔ)言》第 11 課 —— 千軍萬(wàn)馬跑協(xié)程《快學(xué) Go 語(yǔ)言》第 12 課 —— 通道let's ...
    合肥黑閱讀 2,916評(píng)論 2 7
  • 1. cpu通過(guò)時(shí)間片分配算法來(lái)循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行一個(gè)時(shí)間片后會(huì)切換到下一任務(wù)冲呢。但是舍败,再切換之前會(huì)保存上一...
    冰與河豚魚(yú)閱讀 668評(píng)論 0 0