第06天(并發(fā)編程)_01

01_創(chuàng)建goroutine.go

package main
import (
    "fmt"
    "time"
)
func newTask() {
    for {
        fmt.Println("this is a newTask")
        time.Sleep(time.Second) //延時1s
    }
}
func main() {
    go newTask() //新建一個協(xié)程昭灵, 新建一個任務(wù)
    for {
        fmt.Println("this is a main goroutine")
        time.Sleep(time.Second) //延時1s
    }
}

02_主goroutine先退出.go

package main

import (
    "fmt"
    "time"
)
//主協(xié)程退出了,其它子協(xié)程也要跟著退出
func main() {
    go func() {
        i := 0
        for {
            i++
            fmt.Println("子協(xié)程 i = ", i)
            time.Sleep(time.Second)
        }

    }() //別忘了()
    i := 0
    for {
        i++
        fmt.Println("main i = ", i)
        time.Sleep(time.Second)

        if i == 2 {
            break
        }
    }
}

03_主協(xié)程先退出導(dǎo)致子協(xié)程沒有來得及調(diào)用.go

package main

import (
    "fmt"
    "time"
)

//主協(xié)程退出了佳遂,其它子協(xié)程也要跟著退出
func main() {
    go func() {
        i := 0
        for {
            i++
            fmt.Println("子協(xié)程 i = ", i)
            time.Sleep(time.Second)
        }

    }() //別忘了()
}

04_Gosched的使用.go

package main
import (
    "fmt"
    "runtime"
)
func main() {
    go func() {
        for i := 0; i < 5; i++ {
            fmt.Println("go")
        }
    }()
    for i := 0; i < 2; i++ {
        //讓出時間片蚤蔓,先讓別的協(xié)議執(zhí)行吊奢,它執(zhí)行完,再回來執(zhí)行此協(xié)程
        runtime.Gosched()
        fmt.Println("hello")
    }
}

05_Goexit的使用.go

package main

import (
    "fmt"
    "runtime"
)

func test() {
    defer fmt.Println("ccccccccccccc")
    //return //終止此函數(shù)
    runtime.Goexit() //終止所在的協(xié)程
    fmt.Println("dddddddddddddddddddddd")
}

func main() {
    //創(chuàng)建新建的協(xié)程
    go func() {
        fmt.Println("aaaaaaaaaaaaaaaaaa")
        //調(diào)用了別的函數(shù)
        test()
        fmt.Println("bbbbbbbbbbbbbbbbbbb")
    }() //別忘了()
    //特地寫一個死循環(huán),目的不讓主協(xié)程結(jié)束
    for {
    }
}

06_GOMAXPROCS的使用.go

package main

import (
    "fmt"
    "runtime"
)
func main() {
    //n := runtime.GOMAXPROCS(1) //指定以1核運(yùn)算
    n := runtime.GOMAXPROCS(4) //指定以4核運(yùn)算
    fmt.Println("n = ", n)
    for {
        go fmt.Print(1)
        fmt.Print(0)
    }
}

07_多任務(wù)資源競爭問題.go

package main

import (
    "fmt"
    "time"
)

//定義一個打印機(jī)丁寄,參數(shù)為字符串,按每個字符打印
//打印機(jī)屬于公共資源
func Printer(str string) {
    for _, data := range str {
        fmt.Printf("%c", data)
        time.Sleep(time.Second)
    }
    fmt.Printf("\n")
}

func person1() {
    Printer("hello")
}

func person2() {
    Printer("world")
}

func main() {
    //新建2個協(xié)程泊愧,代表2個人伊磺,2個人同時使用打印機(jī)
    go person1()
    go person2()

    //特地不讓主協(xié)程結(jié)束,死循環(huán)
    for {

    }
}

08_通過channel實(shí)現(xiàn)同步.go

package main

import (
    "fmt"
    "time"
)

//全局變量删咱,創(chuàng)建一個channel
var ch = make(chan int)

//定義一個打印機(jī)屑埋,參數(shù)為字符串,按每個字符打印
//打印機(jī)屬于公共資源
func Printer(str string) {
    for _, data := range str {
        fmt.Printf("%c", data)
        time.Sleep(time.Second)
    }
    fmt.Printf("\n")
}

//person1執(zhí)行完后痰滋,才能到person2執(zhí)行
func person1() {
    Printer("hello")
    ch <- 666 //給管道寫數(shù)據(jù)摘能,發(fā)送
}

func person2() {
    <-ch //從管道取數(shù)據(jù),接收敲街,如果通道沒有數(shù)據(jù)他就會阻塞
    Printer("world")
}

func main() {
    //新建2個協(xié)程徊哑,代表2個人,2個人同時使用打印機(jī)
    go person1()
    go person2()

    //特地不讓主協(xié)程結(jié)束聪富,死循環(huán)
    for {

    }
}

09_通過channel實(shí)現(xiàn)同步和數(shù)據(jù)交互.go

package main

import (
    "fmt"
    "time"
)

func main() {
    //創(chuàng)建channel
    ch := make(chan string)
    defer fmt.Println("主協(xié)程也結(jié)束")
    go func() {
        defer fmt.Println("子協(xié)程調(diào)用完畢")
        for i := 0; i < 2; i++ {
            fmt.Println("子協(xié)程 i = ", i)
            time.Sleep(time.Second)
        }
        ch <- "我是子協(xié)程莺丑,要工作完畢"
    }()
    str := <-ch //沒有數(shù)據(jù)前,阻塞
    fmt.Println("str = ", str)
}

10_無緩沖的channel.go

package main

import (
    "fmt"
    "time"
)

func main() {
    //創(chuàng)建一個無緩存的channel
    ch := make(chan int, 0)

    //len(ch)緩沖區(qū)剩余數(shù)據(jù)個數(shù), cap(ch)緩沖區(qū)大小
    fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch))

    //新建協(xié)程
    go func() {
        for i := 0; i < 3; i++ {
            fmt.Printf("子協(xié)程:i = %d\n", i)
            ch <- i //往chan寫內(nèi)容
        }
    }()

    //延時
    time.Sleep(2 * time.Second)

    for i := 0; i < 3; i++ {
        num := <-ch //讀管道中內(nèi)容梢莽,沒有內(nèi)容前萧豆,阻塞
        fmt.Println("num = ", num)
    }
}

11_有緩沖的channel.go

package main

import (
    "fmt"
    "time"
)

func main() {
    //創(chuàng)建一個有緩存的channel
    ch := make(chan int, 3)

    //len(ch)緩沖區(qū)剩余數(shù)據(jù)個數(shù), cap(ch)緩沖區(qū)大小
    fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch))

    //新建協(xié)程
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i //往chan寫內(nèi)容
            fmt.Printf("子協(xié)程[%d]: len(ch) = %d, cap(ch)= %d\n", i, len(ch), cap(ch))
        }
    }()

    //延時
    time.Sleep(2 * time.Second)

    for i := 0; i < 10; i++ {
        num := <-ch //讀管道中內(nèi)容昏名,沒有內(nèi)容前涮雷,阻塞
        fmt.Println("num = ", num)
    }

}

12_關(guān)閉channel.go

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int) //創(chuàng)建一個無緩存channel

    //新建一個goroutine
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i //往通道寫數(shù)據(jù)
        }
        //不需要再寫數(shù)據(jù)時,關(guān)閉channel
        close(ch)
        //ch <- 666 //關(guān)閉channel后無法再發(fā)送數(shù)據(jù)

    }() //別忘了()

    for num := range ch {
        fmt.Println("num = ", num)
    }

}

func main01() {
    ch := make(chan int) //創(chuàng)建一個無緩存channel

    //新建一個goroutine
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i //往通道寫數(shù)據(jù)
        }
        //不需要再寫數(shù)據(jù)時轻局,關(guān)閉channel
        close(ch)
        //ch <- 666 //關(guān)閉channel后無法再發(fā)送數(shù)據(jù)

    }() //別忘了()

    for {
        //如果ok為true洪鸭,說明管道沒有關(guān)閉
        if num, ok := <-ch; ok == true {
            fmt.Println("num = ", num)
        } else { //管道關(guān)閉
            break
        }
    }

}

13_單向channel的特性.go

package main

//"fmt"

func main() {
    //創(chuàng)建一個channel, 雙向的
    ch := make(chan int)

    //雙向channel能隱式轉(zhuǎn)換為單向channel
    var writeCh chan<- int = ch //只能寫,不能讀
    var readCh <-chan int = ch  //只能讀仑扑,不能寫

    writeCh <- 666 //寫
    //<-writeCh //err,  invalid operation: <-writeCh (receive from send-only type chan<- int)

    <-readCh //讀
    //readCh <- 666 //寫览爵, err,  invalid operation: readCh <- 666 (send to receive-only type <-chan int)

    //單向無法轉(zhuǎn)換為雙向
    //var ch2 chan int = writeCh //cannot use writeCh (type chan<- int) as type chan int in assignment

}

14_單向channel的應(yīng)用.go

package main

import (
    "fmt"
)

//此通道只能寫,不能讀
func producer(out chan<- int) {
    for i := 0; i < 10; i++ {
        out <- i * i
    }
    close(out)
}

//此channel只能讀镇饮,不能寫
func consumer(in <-chan int) {
    for num := range in {
        fmt.Println("num = ", num)
    }
}

func main() {
    //創(chuàng)建一個雙向通道
    ch := make(chan int)

    //生產(chǎn)者蜓竹,生產(chǎn)數(shù)字,寫入channel
    //新開一個協(xié)程
    go producer(ch) //channel傳參储藐,引用傳遞

    //消費(fèi)者俱济,從channel讀取內(nèi)容,打印
    consumer(ch)
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钙勃,一起剝皮案震驚了整個濱河市蛛碌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辖源,老刑警劉巖蔚携,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異同木,居然都是意外死亡浮梢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門彤路,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秕硝,“玉大人,你說我怎么就攤上這事洲尊≡恫颍” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵坞嘀,是天一觀的道長躯护。 經(jīng)常有香客問我,道長丽涩,這世上最難降的妖魔是什么棺滞? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任裁蚁,我火速辦了婚禮硝拧,結(jié)果婚禮上麸恍,老公的妹妹穿的比我還像新娘煮盼。我一直安慰自己三娩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布友鼻。 她就那樣靜靜地躺著忧设,像睡著了一般石挂。 火紅的嫁衣襯著肌膚如雪崔泵。 梳的紋絲不亂的頭發(fā)上秒赤,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機(jī)與錄音憎瘸,去河邊找鬼入篮。 笑死,一個胖子當(dāng)著我的面吹牛含思,可吹牛的內(nèi)容都是我干的崎弃。 我是一名探鬼主播甘晤,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼含潘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了线婚?” 一聲冷哼從身側(cè)響起遏弱,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎塞弊,沒想到半個月后漱逸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡游沿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年饰抒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诀黍。...
    茶點(diǎn)故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡袋坑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出眯勾,到底是詐尸還是另有隱情枣宫,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布吃环,位于F島的核電站也颤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏郁轻。R本人自食惡果不足惜翅娶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竭沫,春花似錦厂庇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贯溅,卻和暖如春拄氯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背它浅。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工译柏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姐霍。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓鄙麦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親镊折。 傳聞我的和親對象是個殘疾皇子胯府,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評論 2 345

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