golang核心Goroutine和channel

1、Goroutine

 

一、介紹

goroutine簡介 goroutine是go語言中最爲NB的設計,也是其魅力所在,goroutine的本質是協程,是實現並行計算的核心。goroutine使用方式很是的簡單,只需使用go關鍵字便可啓動一個協程,而且它是處於異步方式運行,你不須要等它運行完成之後在執行之後的代碼。html

一、 主線程是一個物理線程,直接做用在 cpu 上的。是重量級的,很是耗費 cpu 資源。編程

二、 協程從主線程開啓的,是輕量級的線程,是邏輯態。對資源消耗相對小。安全

三、 Golang 的協程機制是重要的特色,能夠輕鬆的開啓上萬個協程。其它編程語言的併發機制是通常基於線程的,開啓過多的線程,資源耗費大,這裏就突顯 Golang 在併發上的優數據結構

四、goroutine經過go關鍵字實現了,其實就是一個普通的函數。併發

 

爲了充分了利用多 cpu 的優點,在 Golang 程序中,設置運行的 cpu 數目(Go1.8之後默認運行在多核上)異步

num := runtime.NumCPU()    //本地機器的邏輯CPU個數
runtime.GOMAXPROCS(num)    //設置可同時執行的最大CPU數,並返回先前的設置
fmt.Println(num)

 

  

 

二、執行流程圖

 

 

三、簡單例子

package main
import (
    "fmt"
    "time"
)

func test(){
    for i := 1;i <= 10;i++ {
        fmt.Println(i)
        time.Sleep(time.Second * 2 ) //睡眠2s        
    }

}

func main(){
    go test() //開啓協程
    for i := 1;i <= 10;i++ {
        fmt.Println("===============")
        time.Sleep(time.Second  ) //睡眠1s        
        
    }
}


#########結果######
===============
1
===============
===============
2
===============
3
===============
===============
4
===============
===============
5
===============
===============
6

  

四、使用全局變量加鎖的例子

計算0-10的乘階編程語言

 代碼:函數

package main

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

var (
    m    = make(map[int]uint64)
    //lock是一個全局互斥鎖
    //sync.Mutex 是互斥鎖
    lock sync.Mutex //申明一個互斥鎖
)

type task struct {
    n int
}

func calc(t *task) {
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println("error...")
            return
        }
    }()

    var sum uint64
    sum = 1
    for i := 1; i < t.n; i++ {
        sum *= uint64(i)
    }

    lock.Lock() //加鎖
    m[t.n] = sum
    lock.Unlock() //解鎖
}

func main() {
    for i := 0; i <= 10; i++ {
        t := &task{n: i}
        go calc(t) // Goroutine來執行任務
    }

    time.Sleep(time.Second) // Goroutine異步,因此等一秒到任務完成

    lock.Lock() //讀全局數據加鎖
    for k, v := range m {
        fmt.Printf("%d! = %v\n", k, v)
    }
    fmt.Println(len(m))
    lock.Unlock() //解鎖
}


#########結果#######
10! = 362880
0! = 1
2! = 1
3! = 2
4! = 6
5! = 24
7! = 720
8! = 5040
1! = 1
6! = 120
9! = 40320
11

  

2、channel 

channel 的基本介紹

一、channle 本質就是一個數據結構-隊列ui

二、數據是先進先出spa

三、線程安全,多 goroutine 訪問時,不須要加鎖,就是說 channel 自己就是線程安全的

四、channel 有類型的,一個 string 的 channel 只能存放 string 類型數

示意圖:

 

 

文檔參考:

http://www.cnblogs.com/wdliu/p/9272220.html

 

channel 使用的注意事項

一、channel 中只能存放指定的數據類型

二、channle 的數據放滿後,就不能再放入了

三、若是從 channel 取出數據後,能夠繼續放入

四、在沒有使用協程的狀況下,若是 channel 數據取完了,再取,就會報 dead lock

相關文章
相關標籤/搜索