日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
Go1.16中的新函數Signal.NotifyContext怎么用?

大家好,我是 polarisxu。

和靜網站制作公司哪家好,找成都創(chuàng)新互聯!從網頁設計、網站建設、微信開發(fā)、APP開發(fā)、成都響應式網站建設公司等網站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯自2013年創(chuàng)立以來到現在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網站建設就選成都創(chuàng)新互聯

os/signal 這個包大家可能用的不多。但自從 Go1.8 起,有些人開始使用這個包了,原因是 Go1.8 在 net/http 包新增了一個方法:

 
 
 
 
  1. func (srv *Server) Shutdown(ctx context.Context) error 

有了它就不需要借助第三方庫實現優(yōu)雅關閉服務了。具體怎么做呢?

 
 
 
 
  1. func main() { 
  2.  server = http.Server{ 
  3.   Addr: ":8080", 
  4.  } 
  5.  
  6.  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 
  7.   time.Sleep(time.Second * 10) 
  8.   fmt.Fprint(w, "Hello world!") 
  9.  }) 
  10.    
  11.  go server.ListenAndServe() 
  12.  
  13.  // 監(jiān)聽中斷信號(CTRL + C) 
  14.  c := make(chan os.Signal, 1) 
  15.  signal.Notify(c, os.Interrupt) 
  16.  <-c 
  17.  
  18.  // 重置 os.Interrupt 的默認行為 
  19.  signal.Reset(os.Interrupt) 
  20.  
  21.  fmt.Println("shutting down gracefully, press Ctrl+C again to force") 
  22.  
  23.  // 給程序最多 5 秒時間處理正在服務的請求 
  24.  timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 
  25.  defer cancel() 
  26.  
  27.  if err := server.Shutdown(timeoutCtx); err != nil { 
  28.   fmt.Println(err) 
  29.  } 
  • 這里利用 os/signal 包監(jiān)聽 Interrupt 信號;
  • 收到該信號后,16 行 <-c 會返回;
  • 為了可以再次 CTRL + C 強制退出,通過 Reset 恢復 os.Interrupt 的默認行為;(這不是必須的)

優(yōu)雅退出的關鍵:1)新請求進不來;2)已有請求給時間處理完。所以,在接收到信號后,調用 server.Shutdown 方法,阻止新請求進來,同時給 5 秒等待時間,讓已經進來的請求有時間處理。

在 Go1.16 中,os/signal 包新增了一個函數:

 
 
 
 
  1. func NotifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) 

功能和 Notify 類似,但用法上有些不同。上面的例子改用 NotifyContext:

 
 
 
 
  1. func after() { 
  2.  server = http.Server{ 
  3.   Addr: ":8080", 
  4.  } 
  5.  
  6.  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 
  7.   time.Sleep(time.Second * 10) 
  8.   fmt.Fprint(w, "Hello world!") 
  9.  }) 
  10.  
  11.  go server.ListenAndServe() 
  12.   
  13.   // 監(jiān)聽中斷信號(CTRL + C) 
  14.  ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) 
  15.  <-ctx.Done() 
  16.  
  17.   // 重置 os.Interrupt 的默認行為,類似 signal.Reset 
  18.  stop() 
  19.  fmt.Println("shutting down gracefully, press Ctrl+C again to force") 
  20.  
  21.   // 給程序最多 5 秒時間處理正在服務的請求 
  22.  timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 
  23.  defer cancel() 
  24.  
  25.  if err := server.Shutdown(timeoutCtx); err != nil { 
  26.   fmt.Println(err) 
  27.  } 

和上面的寫法有區(qū)別,完成的功能一樣的。其實 NotifyContext 的內部就是基于 Notify 實現的:

 
 
 
 
  1. func NotifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) { 
  2.  ctx, cancel := context.WithCancel(parent) 
  3.  c := &signalCtx{ 
  4.   Context: ctx, 
  5.   cancel:  cancel, 
  6.   signals: signals, 
  7.  } 
  8.  c.ch = make(chan os.Signal, 1) 
  9.  Notify(c.ch, c.signals...) 
  10.  if ctx.Err() == nil { 
  11.   go func() { 
  12.    select { 
  13.    case <-c.ch: 
  14.     c.cancel() 
  15.    case <-c.Done(): 
  16.    } 
  17.   }() 
  18.  } 
  19.  return c, c.stop 

只是在返回的 stop 被調用時,會執(zhí)行 os/signal 包中的 Stop 函數,這個 Stop 函數的功能和 Reset 類似。因此上面 Notify 的例子,Reset 的地方可以改為 Stop。

從封裝上看,NotifyContext 做的更好。而且,如果在某些需要 Context 的場景下,它把監(jiān)控系統信號和創(chuàng)建 Context 一步搞定。

NotifyContext 的用法,優(yōu)雅的關閉服務,你掌握了嗎?希望你實際動手試驗下,啟動服務,通過 curl http://localhost:8080/ 訪問,然后按 CTRL + C,看看具體效果。只看不動手,基本知識不是你的。

關于 NotifyContext 函數的文檔可以在這里查看:https://docs.studygolang.com/pkg/os/signal/#NotifyContext。

本文轉載自微信公眾號「polarisxu」,可以通過以下二維碼關注。轉載本文請聯系polarisxu公眾號。


本文題目:Go1.16中的新函數Signal.NotifyContext怎么用?
文章鏈接:http://www.5511xx.com/article/ccopsdg.html