最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GOLANG使用Context管理關(guān)聯(lián)goroutine的方法

 更新時間:2019年01月14日 09:32:48   作者:winlin  
這篇文章主要介紹了GOLANG使用Context管理關(guān)聯(lián)goroutine的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一般一個業(yè)務(wù)很少不用到goroutine的,因為很多方法是需要等待的,例如http.Server.ListenAndServe這個就是等待的,除非關(guān)閉了Server或Listener,否則是不會返回的。除非是一個API服務(wù)器,否則肯定需要另外起goroutine發(fā)起其他的服務(wù),而且對于API服務(wù)器來說,在http.Handler的處理函數(shù)中一般也需要起goroutine,如何管理這些goroutine,在GOLANG1.7提供context.Context

先看一個簡單的,如果啟動兩個goroutine,一個是HTTP,還有個信號處理的收到退出信號做清理:

wg := sync.WaitGroup{}
defer wg.Wait()

wg.Add(1)
go func() {
  defer wg.Done()

  ss := make(os.Signal, 0)
  signal.Notify(ss, syscall.SIGINT, syscall.SIGTERM)
  for s := ss {
    fmt.Println("Got signal", s)
    break
  }
}()

wg.Add(1)
go func() {
  defer wg.Done()

  svr := &http.Server{ Addr:":8080", Handler:nil, }
  fmt.Println(svr.ListenAndServe())
}

很清楚,起了兩個goroutine,然后用WaitGroup等待它們退出。如果它們之間沒有交互,不互相影響,那真的是蠻簡單的,可惜這樣是不行的,因為信號的goroutine收到退出信號后,應(yīng)該通知server退出。暴力一點的是直接調(diào)用svr.Close(),但是如果有些請求還需要取消怎么辦呢?最好用Context了:

wg := sync.WaitGroup{}
defer wg.Wait()

ctx,cancel := context.WithCancel(context.Background())

wg.Add(1)
go func() {
  defer wg.Done()

  ss := make(chan os.Signal, 0)
  signal.Notify(ss, syscall.SIGINT, syscall.SIGTERM)
  select {
  case <- ctx.Done():
    return
  case s := <- ss:
    fmt.Println("Got signal", s)
    cancel() // 取消請求,通知用到ctx的所有g(shù)oroutine
    return
  }
}()

wg.Add(1)
go func() {
  defer wg.Done()
  defer cancel()

  svr := &http.Server{ Addr:":8080", Handler:nil, }

  go func(){
    select {
    case <- ctx.Done():
      svr.Close()
    }
  }

  fmt.Println(svr.ListenAndServe())
}

這個方式可以在新開goroutine時繼續(xù)使用,譬如新加一個goroutine,里面讀寫了UDPConn:

wg.Add(1)
go func() {
  defer wg.Done()
  defer cancel()

  var conn *net.UDPConn
  if conn,err = net.Dial("udp", "127.0.0.1:1935"); err != nil {
    fmt.Println("Dial UDP server failed, err is", err)
    return
  }

  fmt.Println(UDPRead(ctx, conn))
}()

UDPRead = func(ctx context.Context, conn *net.UDPConn) (err error) {
  wg := sync.WaitGroup{}
  defer wg.Wait()

  ctx, cancel := context.WithCancel(ctx)

  wg.Add(1)
  go func() {
    defer wg.Done()
    defer cancel()

    for {
      b := make([]byte, core.MTUSize)
      size, _, err := conn.ReadFromUDP(b)
      // 處理UDP包 b[:size]
    }
  }()

  select {
  case <-ctx.Done():
    conn.Close()
  }
  return
}

如果只是用到HTTP Server,可以這么寫:

func run(ctx contex.Context) {
  server := &http.Server{Addr: addr, Handler: nil}
  go func() {
    select {
    case <-ctx.Done():
      server.Close()
    }
  }()

  http.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
  })

  fmt.Println(server.ListenAndServe())
}

如果需要提供一個API來讓服務(wù)器退出,可以這么寫:

func run(ctx contex.Context) {
  server := &http.Server{Addr: addr, Handler: nil}

  ctx, cancel := context.WithCancel(ctx)
  http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
    cancel() // 使用局部的ctx和cancel
  })

  go func() {
    select {
    case <-ctx.Done():
      server.Close()
    }
  }()

  fmt.Println(server.ListenAndServe())
}

使用局部的ctx和cancel,可以避免cancel傳入的ctx,只是影響當(dāng)前的ctx。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Go項目怎么使用枚舉

    Go項目怎么使用枚舉

    枚舉是一種很重要的數(shù)據(jù)類型,本文主要介紹了Go項目怎么使用枚舉,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Golang使用bcrypt實現(xiàn)密碼加密和校驗的操作代碼

    Golang使用bcrypt實現(xiàn)密碼加密和校驗的操作代碼

    bcrypt可以用于數(shù)據(jù)庫中的用戶密碼保存,相比md5而言更加的安全可靠,這篇文章主要介紹了Golang使用bcrypt實現(xiàn)密碼加密和校驗的操作代碼,需要的朋友可以參考下
    2024-05-05
  • Golang如何實現(xiàn)任意進制轉(zhuǎn)換的方法示例

    Golang如何實現(xiàn)任意進制轉(zhuǎn)換的方法示例

    進制轉(zhuǎn)換是人們利用符號來計數(shù)的方法,進制轉(zhuǎn)換由一組數(shù)碼符號和兩個基本因素“基數(shù)”與“位權(quán)”構(gòu)成,這篇文章主要給大家介紹了關(guān)于Golang如何實現(xiàn)10進制轉(zhuǎn)換62進制的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí)學(xué)習(xí),下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • 深入了解Golang?哈希算法之MD5、SHA-1和SHA-256

    深入了解Golang?哈希算法之MD5、SHA-1和SHA-256

    哈希算法是計算機科學(xué)領(lǐng)域中一種重要的技術(shù),它將任意長度的輸入數(shù)據(jù)映射為固定長度的哈希值,在本篇文章中,我們將深入探討Golang中的哈希算法,從多個方面介紹其詳細(xì)內(nèi)容,希望通過本文的閱讀你將對?Golang哈希算法有更全面的理解
    2023-05-05
  • Mango?Cache緩存管理庫TinyLFU源碼解析

    Mango?Cache緩存管理庫TinyLFU源碼解析

    這篇文章主要為大家介紹了Mango?Cache緩存管理庫TinyLFU源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • go原子級內(nèi)存操作實現(xiàn)

    go原子級內(nèi)存操作實現(xiàn)

    原子級內(nèi)存操作是在多線程并發(fā)執(zhí)行時,能夠確保某個內(nèi)存操作是不可中斷的操作,本文主要介紹了go原子級內(nèi)存操作實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • 一文帶你掌握Go語言運算符的使用

    一文帶你掌握Go語言運算符的使用

    運算符用于在程序運行時執(zhí)行數(shù)學(xué)或邏輯運算。Go 語言內(nèi)置的運算符有:算術(shù)運算符、關(guān)系運算符、邏輯運算符、位運算符、賦值運算符、其他運算符。本文將帶大家詳細(xì)了解一下這些運算符的使用,感興趣的可以了解一下
    2022-04-04
  • Go與C語言的互操作實現(xiàn)

    Go與C語言的互操作實現(xiàn)

    在Go與C語言互操作方面,Go更是提供了強大的支持。尤其是在Go中使用C,你甚至可以直接在Go源文件中編寫C代碼,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-12-12
  • golang代碼中調(diào)用Linux命令

    golang代碼中調(diào)用Linux命令

    本文主要介紹了golang代碼中調(diào)用Linux命令,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • gorm整合進go-zero的實現(xiàn)方法

    gorm整合進go-zero的實現(xiàn)方法

    go-zero提供的代碼生成器里面,沒有提供orm框架操作,但是提供了遍歷的緩存操作,所以可以利用gorm當(dāng)作一個sql語句的生成器,把生成后的sql語句放到go-zero生成的模板中去執(zhí)行,對gorm整合進go-zero的實現(xiàn)方法感興趣的朋友一起看看吧
    2022-03-03

最新評論

宜兴市| 水城县| 嘉善县| 汝南县| 滦南县| 祁阳县| 车致| 钦州市| 达州市| 聊城市| 吉木乃县| 辰溪县| 华容县| 洛阳市| 建水县| 家居| 富裕县| 洪泽县| 宁强县| 公安县| 郴州市| 怀来县| 普格县| 扎鲁特旗| 奎屯市| 聂拉木县| 南澳县| 潢川县| 寻乌县| 五指山市| 武鸣县| 永城市| 贡嘎县| 巨鹿县| 巩留县| 普兰店市| 崇礼县| 崇义县| 百色市| 视频| 繁昌县|