91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言同步與異步執行多個任務封裝的示例分析

發布時間:2021-06-24 09:44:20 來源:億速云 閱讀:133 作者:小新 欄目:編程語言

這篇文章主要介紹了Go語言同步與異步執行多個任務封裝的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

同步執行類RunnerAsync

支持返回超時檢測,系統中斷檢測

錯誤常量定義

//超時錯誤
var ErrTimeout = errors.New("received timeout")
//操作系統系統中斷錯誤
var ErrInterrupt = errors.New("received interrupt")

實現代碼如下

package task
import (
 "os"
 "time"
 "os/signal"
 "sync"
)
 
//異步執行任務
type Runner struct {
 //操作系統的信號檢測
 interrupt chan os.Signal
 //記錄執行完成的狀態
 complete chan error
 //超時檢測
 timeout <-chan time.Time
 //保存所有要執行的任務,順序執行
 tasks []func(id int) error
 waitGroup sync.WaitGroup
 lock sync.Mutex
 errs []error
}
 
//new一個Runner對象
func NewRunner(d time.Duration) *Runner {
 return &Runner{
 interrupt: make(chan os.Signal, 1),
 complete: make(chan error),
 timeout: time.After(d),
 waitGroup: sync.WaitGroup{},
 lock: sync.Mutex{},
 }
}
 
//添加一個任務
func (this *Runner) Add(tasks ...func(id int) error) {
 this.tasks = append(this.tasks, tasks...)
}
 
//啟動Runner,監聽錯誤信息
func (this *Runner) Start() error {
 //接收操作系統信號
 signal.Notify(this.interrupt, os.Interrupt)
 //并發執行任務
 go func() {
 this.complete <- this.Run()
 }()
 select {
 //返回執行結果
 case err := <-this.complete:
 return err
 //超時返回
 case <-this.timeout:
 return ErrTimeout
 }
}
 
//異步執行所有的任務
func (this *Runner) Run() error {
 for id, task := range this.tasks {
 if this.gotInterrupt() {
  return ErrInterrupt
 }
 this.waitGroup.Add(1)
 go func(id int) {
  this.lock.Lock()
  //執行任務
  err := task(id)
  //加鎖保存到結果集中
  this.errs = append(this.errs, err)
 
  this.lock.Unlock()
  this.waitGroup.Done()
 }(id)
 }
 this.waitGroup.Wait()
 
 return nil
}
 
//判斷是否接收到操作系統中斷信號
func (this *Runner) gotInterrupt() bool {
 select {
 case <-this.interrupt:
 //停止接收別的信號
 signal.Stop(this.interrupt)
 return true
 //正常執行
 default:
 return false
 }
}
 
//獲取執行完的error
func (this *Runner) GetErrs() []error {
 return this.errs
}

使用方法    

Add添加一個任務,任務為接收int類型的一個閉包

Start開始執行傷,返回一個error類型,nil為執行完畢, ErrTimeout代表執行超時,ErrInterrupt代表執行被中斷(類似Ctrl + C操作)

測試示例代碼

package task
import (
 "testing"
 "time"
 "fmt"
 "os"
 "runtime"
)
 
func TestRunnerAsync_Start(t *testing.T) {
 //開啟多核
 runtime.GOMAXPROCS(runtime.NumCPU())
 //創建runner對象,設置超時時間
 runner := NewRunnerAsync(8 * time.Second)
 //添加運行的任務
 runner.Add(
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 createTaskAsync(),
 )
 fmt.Println("同步執行任務")
 //開始執行任務
 if err := runner.Start(); err != nil {
 switch err {
 case ErrTimeout:
  fmt.Println("執行超時")
  os.Exit(1)
 case ErrInterrupt:
  fmt.Println("任務被中斷")
  os.Exit(2)
 }
 }
 t.Log("執行結束")
}
 
//創建要執行的任務
func createTaskAsync() func(id int) {
 return func(id int) {
 fmt.Printf("正在執行%v個任務\n", id)
 //模擬任務執行,sleep兩秒
 //time.Sleep(1 * time.Second)
 }
}

執行結果  

同步執行任務
正在執行0個任務
正在執行1個任務
正在執行2個任務
正在執行3個任務
正在執行4個任務
正在執行5個任務
正在執行6個任務
正在執行7個任務
正在執行8個任務
正在執行9個任務
正在執行10個任務
正在執行11個任務
正在執行12個任務
 runnerAsync_test.go:49: 執行結束

異步執行類Runner

支持返回超時檢測,系統中斷檢測

實現代碼如下

package task
import (
 "os"
 "time"
 "os/signal"
 "sync"
)
 
//異步執行任務
type Runner struct {
 //操作系統的信號檢測
 interrupt chan os.Signal
 //記錄執行完成的狀態
 complete chan error
 //超時檢測
 timeout <-chan time.Time
 //保存所有要執行的任務,順序執行
 tasks []func(id int) error
 waitGroup sync.WaitGroup
 lock sync.Mutex
 errs []error
}
 
//new一個Runner對象
func NewRunner(d time.Duration) *Runner {
 return &Runner{
  interrupt: make(chan os.Signal, 1),
  complete: make(chan error),
  timeout: time.After(d),
  waitGroup: sync.WaitGroup{},
  lock:  sync.Mutex{},
 }
}
 
//添加一個任務
func (this *Runner) Add(tasks ...func(id int) error) {
 this.tasks = append(this.tasks, tasks...)
}
 
//啟動Runner,監聽錯誤信息
func (this *Runner) Start() error {
 //接收操作系統信號
 signal.Notify(this.interrupt, os.Interrupt)
 //并發執行任務
 go func() {
  this.complete <- this.Run()
 }()
 select {
 //返回執行結果
 case err := <-this.complete:
  return err
  //超時返回
 case <-this.timeout:
  return ErrTimeout
 }
}
 
//異步執行所有的任務
func (this *Runner) Run() error {
 for id, task := range this.tasks {
  if this.gotInterrupt() {
   return ErrInterrupt
  }
  this.waitGroup.Add(1)
  go func(id int) {
   this.lock.Lock()
   //執行任務
   err := task(id)
   //加鎖保存到結果集中
   this.errs = append(this.errs, err)
   this.lock.Unlock()
   this.waitGroup.Done()
  }(id)
 }
 this.waitGroup.Wait()
 return nil
}
 
//判斷是否接收到操作系統中斷信號
func (this *Runner) gotInterrupt() bool {
 select {
 case <-this.interrupt:
  //停止接收別的信號
  signal.Stop(this.interrupt)
  return true
  //正常執行
 default:
  return false
 }
}
 
//獲取執行完的error
func (this *Runner) GetErrs() []error {
 return this.errs
}

使用方法    

Add添加一個任務,任務為接收int類型,返回類型error的一個閉包

Start開始執行傷,返回一個error類型,nil為執行完畢, ErrTimeout代表執行超時,ErrInterrupt代表執行被中斷(類似Ctrl + C操作)

getErrs獲取所有的任務執行結果

測試示例代碼

package task
import (
 "testing"
 "time"
 "fmt"
 "os"
 "runtime"
)
 
func TestRunner_Start(t *testing.T) {
 //開啟多核心
 runtime.GOMAXPROCS(runtime.NumCPU())
 //創建runner對象,設置超時時間
 runner := NewRunner(18 * time.Second)
 //添加運行的任務
 runner.Add(
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
  createTask(),
 )
 fmt.Println("異步執行任務")
 //開始執行任務
 if err := runner.Start(); err != nil {
  switch err {
  case ErrTimeout:
   fmt.Println("執行超時")
   os.Exit(1)
  case ErrInterrupt:
   fmt.Println("任務被中斷")
   os.Exit(2)
  }
 }
 t.Log("執行結束")
 t.Log(runner.GetErrs())
}
 
//創建要執行的任務
func createTask() func(id int) error {
 return func(id int) error {
  fmt.Printf("正在執行%v個任務\n", id)
  //模擬任務執行,sleep
  //time.Sleep(1 * time.Second)
  return nil
 }
}

執行結果

異步執行任務
正在執行2個任務
正在執行1個任務
正在執行4個任務
正在執行3個任務
正在執行6個任務
正在執行5個任務
正在執行9個任務
正在執行7個任務
正在執行10個任務
正在執行13個任務
正在執行8個任務
正在執行11個任務
正在執行12個任務
正在執行0個任務
 runner_test.go:49: 執行結束
 runner_test.go:51: [<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Go語言同步與異步執行多個任務封裝的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潮州市| 汾阳市| 当雄县| 吐鲁番市| 宽甸| 长岛县| 海盐县| 高唐县| 万荣县| 沭阳县| 外汇| 当阳市| 曲阜市| 甘南县| 南汇区| 德州市| 河曲县| 衢州市| 南丹县| 西充县| 辽宁省| 蕉岭县| 颍上县| 祁东县| 昌邑市| 玉门市| 大邑县| 卫辉市| 永清县| 宁武县| 应城市| 兴安盟| 海晏县| 平度市| 中西区| 开封市| 偏关县| 山阳县| 康平县| 婺源县| 营口市|