golang併發練習代碼筆記

golang語言的精髓就是它的併發機制,十分簡單,而且極少數在語言層面實現併發機制的語言,golang被成爲網絡時代的c語言,golang的締造者也有c語言的締造者,Go語言是google程序員

推出的一門靜態語言,自帶方便的命令行工具,簡潔的語法,雖然簡潔可是足夠強大,是編寫高併發服務器理想的語言。golang

在goang中開啓一個新的協程十分簡單,使用go就能夠開一個協程,每須要一個協程就用go開一個。服務器

固然其中有些細節須要注意。網絡

因爲go協程是併發的所以,在使用的時候要注意主協程結束的時候,是不會等待其餘未完成的協程,因此,有關資源競爭就引出channel來解決資源競爭的問題,併發

屏幕的輸出也是一種資源競爭所以在下面的練習代碼中使用了打印字符的方式體現併發機制,和資源競爭。函數

go語言推行使通訊來實現資源競爭產生的混亂和丟失問題。高併發

 1 package main
 2 import 「fmt」
 3 
 4 func main() {
 5     go func(){
 6         fmt.Println("協程一")
 7     }()
 8     go func(){
 9         fmt.Println("協程二")
10     }()
11     fmt.Println("結束")
12 }
13 這個例子只能輸出「結束」
14 由於主協程已經結束運行了,併發協程來不及打印,主協程不會等待其餘goroutine結束,
15 加入channel以後,就能夠實現協程之間的通訊機制,感覺到golang的設計哲學。

一樣是上面的例子,咱們經過加入chan類型的通訊消息變量解決上面程序的問題工具

 

 1 var chani chan int
 2 var chanj chan int
 3 func main() {
 4         go func() {
 5             fmt.Println("協程一")
 6             chani <- 1
 7             chanj <-2
 8         }()
 9 
10 
11         go func() {
12 
13             fmt.Println("協程二")
14             <-chani
15             close(chani)
16             }()
17         runtime.Gosched()     //這個函數能夠出讓執行時間片,讓別的協程執行
18         fmt.Println("結束")
19 }

channel是能夠定義單向的消息ui

1 ch :=make(chan int)    //建立一個雙向的消息channel
2 
3 var channel1 <-chan int =ch    //只讀
4 var channel2 chan<- int =ch     //只寫

定時器,也是經過channel來實現延時的過程google

1 func main() {
2     //計時器的使用
3     for i := 0; i < 10; i++ {
4         timer := time.NewTimer(2 * time.Second)
5         fmt.Println("如今時間:", time.Now())
6         t := <-timer.C
7         fmt.Println(t, "\n", timer)
8     }
9 }
1 計時器是能夠重置,和中止
2 timer.Stop()
3 timer.Reset()

在golang語言中有了channel,也引出了select

經過select語句能夠監聽channel上的數據流活動

select語句很像switch語句,由select語句

1 select{
2     case <-chan1:
3           //若是chan1讀到數據,則該case處理數據
4     case <-1:
5          //若是成功寫入數據,則該case處理
6      default:
7           //默認

select語句有不少的限制條件的

每一個case語句必須是一個IO操做

若是任意一個可執行,選任意一個

若是沒有default語句,沒有知足case的時候,就會阻塞直到有case語句知足

用select實現斐波那契數列。(程序來源黑馬程序員網絡教程)

func fibonacci(ch chan<- int ,quit <-chan bool){
    x,y :=1,1
    for {
        //監聽channel數據流動
        select{
        case ch<-x:
            x,y=y,x+y
        case flag:=<-quit:
              fmt.Println("flag=:",flag)
              return
              }
    }
}

func main(){
    ch :=make(chan int)
    quit :=make(chan bool)
    go func(){
          for i:=0;i<10;i++{
              num:=<-ch
              fmt.Println(num)
          }
          quit<-true
    }()
    fibonacci(ch,quit)
}
相關文章
相關標籤/搜索