<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Golang 協程 && 管道

        1 package threadts
        2 
        3 import (
        4     "fmt"
        5     "runtime"
        6     "sync"
        7     "time"
        8 )
        9 
       10 /*
       11     Golang中的協程和主線程:gorou
       12         1.一個Go線程上,可以起多個協程.也可以理解成:協程是輕量級的線程[編譯器做優化]
       13         2.Go協程的特點
       14             有獨立的棧空間
       15             共享程序堆空間
       16             調度由用戶控制
       17             協程是輕量級的線程
       18         3.主線程退出了,協程不管有沒有執行完都會終止
       19         4.主線程是一個物理線程,直接作用在cpu上的.是重量級的,非常消耗cpu資源
       20         5.協程從主線程開啟的,是輕量級的線程,是邏輯態.對資源消耗非常小
       21         6.Glang的協程機制是重要的特點,可以輕松的開啟上萬個協程.
       22         7.注意:如果在協程代碼中出現panic,沒有及時用defer+recover來處理,就會導致整個程序崩潰
       23 
       24     MPG
       25         Mc:操作系統的主線程
       26         P:協程執行需要的上下文
       27         G:協程
       28 
       29     編譯的時候加上"-race"參數,即可顯示程序運行存在的資源競爭問題.
       30     go build -race main.go
       31 */
       32 
       33 // 全局變量
       34 var (
       35     myMap   = make(map[int]int, 1)
       36     intChan = make(chan int, 1)
       37 
       38     // 互斥鎖
       39     lock sync.Mutex
       40 )
       41 
       42 /*
       43 A處Sleep,B處不Sleep能運行  結論:管道為空的時候會阻塞
       44 
       45     B處Sleep,A處不Sleep能運行  結論:管道滿了,還要在寫的話就得等有人把數據取走
       46     當所有協程都處于休眠狀態,或者所有協程都退出,而代碼仍然要從空管道讀取,或者往滿了的管道寫入都會報錯(fatal error: all goroutines are asleep - deadlock!)
       47 */
       48 func Test1() {
       49     func1 := func() {
       50         for i := 1; i <= 100; i++ {
       51             fmt.Printf("intChan <- %v \n", i)
       52             intChan <- i
       53             // time.Sleep(time.Second * 1)          // A
       54         }
       55         close(intChan)
       56     }
       57     go func1()
       58     for v := range intChan {
       59         fmt.Printf("%v <- intChan \n", v)
       60         time.Sleep(time.Second * 1) // B
       61     }
       62 }
       63 
       64 func Test2() {
       65     var chan1 chan int = make(chan int, 1)
       66     var chan2 chan string = make(chan string, 1)
       67     func1 := func() {
       68         for {
       69             select { // 注意:在這里break continue不好使。你可以用return   或這帶label去break
       70             case t1 := <-chan1:
       71                 fmt.Println("chan1讀到數據了:", t1)
       72             case t2 := <-chan2:
       73                 fmt.Println("chan2讀到數據了:", t2)
       74             default:
       75                 fmt.Println("func1讀數據被堵塞了!")
       76 
       77             }
       78 
       79             // time.Sleep(time.Second * 1)
       80         }
       81     }
       82     func2 := func() {
       83         for i := 1; i <= 10; i++ {
       84             select {
       85             case chan1 <- i:
       86                 fmt.Printf("chan1 <- %v 成功!\n", i)
       87             case chan2 <- fmt.Sprintf("func2:%v", i):
       88                 fmt.Printf("chan2 <- %v 成功!\n", fmt.Sprintf("func2:%v", i))
       89             default:
       90                 fmt.Println("func2寫數據被堵塞了!")
       91             }
       92             // time.Sleep(time.Second * 1)
       93         }
       94     }
       95     go func1()
       96     go func2()
       97 
       98     time.Sleep(time.Second * 10)
       99 
      100 }
      101 
      102 // 互斥鎖實現乘階
      103 func TestMutex() {
      104     chengjie := func(n int) {
      105         sum := 1
      106         for i := 1; i <= n; i++ {
      107             sum *= i
      108         }
      109         lock.Lock()
      110         myMap[n] = sum
      111         defer lock.Unlock()
      112     }
      113     for i := 1; i <= 200; i++ {
      114         go chengjie(i)
      115     }
      116     time.Sleep(time.Second * 5)
      117     lock.Lock()
      118     for i, v := range myMap {
      119         fmt.Printf("myMap[%d]=%d\n", i, v)
      120     }
      121     defer lock.Unlock()
      122 }
      123 
      124 // 管道實現乘階
      125 func TestChannel() {
      126     /*
      127         管道語法:
      128             var [chanName] chan [type]
      129         使用說明:
      130             1.channel是引用類型
      131             2.channel必須使用make初始化之后才能使用.
      132             3.make()初始化時指定的容量是固定的
      133             4.管道為空的時候去讀會阻塞,管道已滿的時候去寫也會阻塞
      134             5.當所有協程都處于休眠狀態,或者所有協程都退出,而代碼仍然要從空管道讀取,或者往滿了的管道寫入都會報錯(fatal error: all goroutines are asleep - deadlock!)
      135             6.從管道中取數據遵循先進先出的規則
      136             7.如果你想讓管道能放任意數據類型,可以指定類型為interface{}.只不過取數據之后需要做一次類型斷言
      137             8.管道關閉之后(Close(chan)內置函數),就不能再往管道里面推數據了,但是可以從管道中讀取數據,直到讀完.
      138             9.如果你要讀取第二個數據的話,必須見推出第一個數據
      139             10.channel支持for-range遍歷,但有兩個注意:
      140                 .在遍歷時,如果channel沒有關閉,則會出現deadlock的錯誤
      141                 .在遍歷時,如果channel已經關閉,則會正常遍歷數據遍歷完成后,就會退出遍歷
      142             11.默認情況下管道是可讀可寫的,但你也可以聲明只讀或者只寫的管道
      143                 只讀管道的聲明: var chan1 <-chan int
      144                 只寫管道的聲明: var chan1 chan<- int
      145                 只讀只寫管道的作用: 在傳參數的時候,可以直接設定管道是否可讀可寫,來減少犯錯
      146             12.可以用select來啟用非阻塞讀取或寫入
      147 
      148 
      149     */
      150 
      151     // 創建一個可以放3個int型數據的管道變量
      152     var intChan chan int
      153     intChan = make(chan int, 3)
      154 
      155     // 往管道寫入數據
      156     intChan <- 10
      157     var ti int = 1
      158     intChan <- ti
      159 
      160     // 查看管道的長度和容量
      161     fmt.Printf("intChan Type=%v, Value=%v, len=%v, cap=%v \n", intChan, intChan, len(intChan), cap(intChan))
      162 
      163     // 從管道中取出數據
      164     ss := <-intChan
      165     fmt.Printf("%v := <-intChan \n", ss)
      166     intChan <- 11
      167 
      168     // 關閉管道
      169     close(intChan)
      170 
      171     // 遍歷管道
      172     for val := range intChan {
      173         fmt.Printf("%v\t", val)
      174     }
      175     fmt.Println()
      176 
      177     fmt.Println("================================")
      178     var waitb chan bool = make(chan bool, 1)
      179     waitb <- false
      180     a, ok := <-waitb
      181     fmt.Printf("a=%v, b=%v\n", a, ok)
      182     waitb <- true
      183     a, ok = <-waitb
      184     fmt.Printf("a=%v, b=%v\n", a, ok)
      185 
      186     fmt.Println("================================")
      187     fmt.Println()
      188 
      189     var cjchan chan int = make(chan int, 200)
      190     var mapChan chan map[int]int = make(chan map[int]int, 1)
      191 
      192     for i := 1; i <= 200; i++ {
      193         cjchan <- i
      194     }
      195     close(cjchan)
      196 
      197     cj := make(map[int]int, 200)
      198     mapChan <- cj
      199 
      200     chengjie := func(c1 chan map[int]int, c2 chan int, c3 chan bool) {
      201         temap := make(map[int]int, 1)
      202         for {
      203             n, ok := <-c2
      204             if !ok {
      205                 break
      206             }
      207             sum := 1
      208             for i := 1; i <= n; i++ {
      209                 sum *= i
      210             }
      211             temap[n] = sum
      212             // fmt.Printf("chengjie %v: %v ok=%v\n", n, sum, ok)
      213         }
      214         imap := <-c1
      215         for i, v := range temap {
      216             imap[i] = v
      217         }
      218         c1 <- imap
      219 
      220         if len(imap) == 200 {
      221             c3 <- true
      222         }
      223     }
      224 
      225     // go chengjie(mapChan, cjchan, waitb)
      226     for i := 1; i <= 10; i++ {
      227         go chengjie(mapChan, cjchan, waitb)
      228     }
      229 
      230     <-waitb
      231     for i, v := range cj {
      232         fmt.Printf("myMap[%d]=%d\n", i, v)
      233     }
      234 
      235 }
      236 
      237 func TestSetCPU() {
      238     // 獲取CPU個數. NumCPU()返回本地機器的邏輯CPU個數
      239     cpuNum := runtime.NumCPU()
      240     fmt.Println("CPU個數=", cpuNum)
      241     // 設置程序執行調度使用CPU個數.默認會自動設置,不需要手動設置
      242     runtime.GOMAXPROCS(cpuNum)
      243 
      244 }
      245 
      246 func TestMain() {
      247     TestGoroutine := func() {
      248         for i := 1; i < 10; i++ {
      249             fmt.Println("TestGoroutine() Hello world!", i)
      250             time.Sleep(time.Second)
      251         }
      252     }
      253     go TestGoroutine()
      254     for i := 1; i < 10; i++ {
      255         fmt.Println("TestMain() Hello world!", i)
      256         time.Sleep(time.Second)
      257     }
      258 
      259 }

       

      鎖\原子操作

       1 func TestSync() {
       2     var lock sync.RWMutex
       3 
       4     lock.Lock()    // "寫"鎖
       5     lock.Unlock()  // "寫"解鎖
       6     lock.RLock()   // "讀"鎖
       7     lock.RUnlock() // "讀"解鎖
       8 
       9     // 數組\切片\結構體都允許并發修改(但會存在臟寫),并發修改map有時候會發生panic
      10     // 如果要修改map可以使用sync.Map
      11     var a sync.Map
      12     a.Store("a", 1)     // add操作
      13     v, _ := a.Load("a") // read操作
      14     fmt.Println(v)
      15 
      16     // 原子操作:并發的時候比如用到i++類似的
      17     var i int32
      18     atomic.AddInt32(&i, 1)
      19     fmt.Println(i)
      20 
      21     // 只執行一次函數
      22     var onece sync.Once
      23     func1 := func() {
      24         onece.Do(func() {
      25             fmt.Println("aaaaa")
      26         })
      27     }
      28     func1()
      29     func1()
      30 
      31 }

       

      posted @ 2023-09-18 13:27  看一百次夜空里的深藍  閱讀(46)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 成人自拍短视频午夜福利| h动态图男女啪啪27报gif| 豆国产97在线 | 亚洲| 国产va免费精品观看精品| 日本熟妇人妻xxxxx人hd| 中文字幕乱码人妻综合二区三区| 久久国产精品久久久久久| 国产偷自一区二区三区在线| 九寨沟县| 无码专区 人妻系列 在线| 内射一区二区三区四区| 欧美不卡无线在线一二三区观| 久久99久久99精品免观看| 国产亚洲欧美另类一区二区| 久久国产精品99久久蜜臀| 动漫AV纯肉无码AV电影网| 亚洲精品一区二区三区综合| 伊人久久大香线蕉av一区二区| 中文国产成人精品久久一| 锡林浩特市| 亚洲高清成人av在线| 人妻无码中文字幕| 四虎成人在线观看免费| 亚洲综合精品第一页| 人妻无码ΑV中文字幕久久琪琪布| 中文日产乱幕九区无线码| 国产精品第一二三区久久| 亚洲人成小说网站色在线| 三男一女吃奶添下面视频| 国产精品一区二区三区黄| 在线涩涩免费观看国产精品| 日本伊人色综合网| 四虎成人精品无码| 亚洲av乱码一区二区| 国色精品卡一卡2卡3卡4卡在线| 国产台湾黄色av一区二区| 国产人妻精品午夜福利免费| 激情五月日韩中文字幕| 国产精品99精品久久免费| 国产av综合色高清自拍| 双峰县|