golang goroutine 介紹

  1. Goroutine 是用戶態本身實現的線程,調度方式遇到IO/阻塞點方式就會讓出cpu時間(其實也看編譯器的實現,若是TA在代碼裏面插入一些yield,也是能夠的。 反正如今不是搶佔式的。)java

  2. 不能設置goroutine ID, 也拿不到(能夠調用C API或者本身修改源碼暴漏出來,實際上修改起來挺簡單的,由於Go的源碼寫的很是簡潔優雅)node

  3. goroutine的棧會自動擴容(初始stack很小,2KB,這也是go程序內存佔用很小的緣由) 4.相對java,多線程調試工具鏈有待完善,不過咱們目前也沒有發現須要這種調試的地方,實在須要時經過profile工具和簡單的日誌就能夠( 目前有一些第三方的工具,不過由於並不須要,咱們也沒有使用過)golang

  4. 開銷很是小,同時運行幾百萬個一點問題都沒有多線程

  5. go func(..) {} ()併發

  6. golang的最大特色就是這個goroutine很是簡單方便,實現功能,都只要按照人類最直接的思惟模式寫就好(反正能夠開大量的goroutine),不像回調的方式那麼碎片化(nodejs),也遠遠不像NIO那麼複雜(netty).一句話:能夠用最簡單的方式寫出來很是高性能的併發函數

package main

import (
    "log"
    "sync"
    "sync/atomic"
    "time"
)

var total int32 = 0

func main() {
    // 控制子線程的任務進行,等同於Map/Reduce處理
    wg := &sync.WaitGroup{}
    // 統計運行時間
    ts := time.Now()
    // 啓動100萬個線程,每一個線程執行100次加1的任務,這裏使用了鎖,防止髒數據
    for i := 0; i < 1000000; i++ {
        // go標記的函數,自動在一個 新的線程中去執行
        go func() {
            // 控制器的執行任務+1
            wg.Add(1)
            // 子線程結束時,控制器的任務執行完成
            defer wg.Done()
            for i := 0; i < 100; i++ {
                atomic.AddInt32(&total, 1)
            }
        }()
    }

    // 這裏主線程休眠一小短期,防止子線程的任務控制wg.Add(1)尚未觸發,主線程就執行完畢
    time.Sleep(1 * time.Millisecond)

    // 等待子線程的任務完成
    wg.Wait()

    // 輸出最終運行時間
    log.Printf("啓動100萬個線程並執行計算任務完成,總計耗時:%v(毫秒)\n", time.Now().Sub(ts).Nanoseconds()/1000000)

    // 輸出最終結果
    log.Println("最終計算結果爲", total)
}
相關文章
相關標籤/搜索