Go language synchronously and asynchronously performs multiple task encapsulation

Source: Internet
Author: User
Tags constant definition
This is a creation in Article, where the information may have evolved or changed.

Synchronization is suitable for multiple consecutive executions, each step of execution is dependent on the previous action, and asynchronous execution is independent of the Order of task execution (e.g. fetching data from 10 sites)

Synchronous Execution Class Runnerasync

Supports return time-out detection, system interrupt detection

Error constant definition

Timeout error var errtimeout = errors. New ("Received timeout")//Operating system interrupt error var Errinterrupt = errors. New ("Received interrupt")

The implementation code is as follows

Package Taskimport ("OS" "Time" "os/signal" "sync")//Asynchronous execution task type Runner struct {//operating system signal detection interrupt C Han os. Signal//Record execution status complete Chan error//timeout detection timeout <-chan time. Time//Save All tasks to be performed in order to perform tasks []func (id int) error waitgroup sync. Waitgroup lock Sync. Mutex errs []error}//new a Runner object 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{},}}//adds a task func (this *runner) Add (Tasks ... func (id int) error) {this.tasks = append (This.tasks, Tasks ...) }//start Runner, monitor error message func (this *runner) Start () error {//Receive operating system signal signal. Notify (This.interrupt, OS. INTERRUPT)//Concurrent Execution Task go func () {This.complete <-this. Run ()} () select {//Return execution result case ERR: = <-this.complete:return Err//Timeout returns case <-this. TimEout:return Errtimeout}}//Asynchronously executes All tasks func (this *runner) the Run () error {for id, Task: = Range This.tasks {             If This.gotinterrupt () {return errinterrupt} this.waitGroup.Add (1) go func (id int) { This.lock.Lock ()//Perform task ERR: = Task (ID)//locking save to result set This.errs = AP Pend (This.errs, Err) This.lock.Unlock () This.waitGroup.Done ()} (ID)} this.waitGroup.Wa        It () return nil}//determines whether the operating system interrupt signal is received by Func (this *runner) Gotinterrupt () bool {Select {case <-this.interrupt: Stop receiving other signal signal. Stop (This.interrupt) return true//normal execution Default:return false}}//get execution finished Errorfunc (this *runner ) Geterrs () []error {return This.errs}

  

How to use

Add adds a task to receive a closure of type int

Start executes the wound, returns an error type, nil is executed, errtimeout represents the execution timeout, errinterrupt represents execution interrupted (like Ctrl + C operation)

Test the sample code

Package Taskimport ("Testing" "Time" "FMT" "OS" "Runtime") func Testrunnerasync_start (t *testing. T) {//Open multi-core runtime. Gomaxprocs (runtime. NUMCPU ())//Create runner object, set timeout Runner: = Newrunnerasync (8 * time). Second)//Add the running task Runner. ADD (Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), create        Taskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (), Createtaskasync (),) fmt. PRINTLN ("Synchronous Execution of tasks")//start the execution of the task if err: = Runner. Start (); Err! = Nil {switch Err {case errtimeout:fmt. Println ("Execution timeout") OS. Exit (1) Case errinterrupt:fmt. Println ("task Interrupted") OS. Exit (2)}} t.Log ("Execution End")}//Create task to perform Func Createtaskasync () func (id int) {return func (id int) {FMT . Printf ("Performing%v tasks \ n", Id)//simulated task execution, sleep two seconds//time. Sleep (1 * time. Second)}}

Execution results

Synchronous execution task executing 0 tasks executing a task executing 2 tasks performing 3 tasks performing 4 tasks performing 5 tasks executing 6 tasks in progress the execution is 7 a task is executing 8 tasks performing 9 tasks executing 10 tasks executing 11 tasks performing a total of six task Runneras ync_test.go:49: End of execution

  

Asynchronous execution class runner

Supports return time-out detection, system interrupt detection

The implementation code is as follows

Package Taskimport ("OS" "Time" "os/signal" "sync")//Asynchronous execution task type Runner struct {//operating system signal detection interrupt C Han os. Signal//Record execution status complete Chan error//timeout detection timeout <-chan time. Time//Save All tasks to be performed in order to perform tasks []func (id int) error waitgroup sync. Waitgroup lock Sync. Mutex errs []error}//new a Runner object 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{},}}//adds a task func (this *runner) Add (Tasks ... func (id int) error) {this.tasks = append (This.tasks, Tasks ...) }//start Runner, monitor error message func (this *runner) Start () error {//Receive operating system signal signal. Notify (This.interrupt, OS. INTERRUPT)//Concurrent Execution Task go func () {This.complete <-this. Run ()} () select {//Return execution result case ERR: = <-this.complete:return Err//Timeout returns case <-this. TimEout:return Errtimeout}}//Asynchronously executes All tasks func (this *runner) the Run () error {for id, Task: = Range This.tasks {             If This.gotinterrupt () {return errinterrupt} this.waitGroup.Add (1) go func (id int) { This.lock.Lock ()//Perform task ERR: = Task (ID)//locking save to result set This.errs = AP Pend (This.errs, Err) This.lock.Unlock () This.waitGroup.Done ()} (ID)} this.waitGroup.Wa        It () return nil}//determines whether the operating system interrupt signal is received by Func (this *runner) Gotinterrupt () bool {Select {case <-this.interrupt: Stop receiving other signal signal. Stop (This.interrupt) return true//normal execution Default:return false}}//get execution finished Errorfunc (this *runner ) Geterrs () []error {return This.errs}

  

How to use

Add a task to receive the int type, return a closure of type error

Start executes the wound, returns an error type, nil is executed, errtimeout represents the execution timeout, errinterrupt represents execution interrupted (like Ctrl + C operation)

Geterrs get all the task execution results

Test the sample code

Package Taskimport ("Testing" "Time" "FMT" "OS" "Runtime") func Testrunner_start (t *testing. T) {//Open multi-core runtime. Gomaxprocs (runtime. NUMCPU ())//Create runner object, set time-out Runner: = Newrunner (*. Second)//Add the running task Runner. ADD (CreateTask (), CreateTask (), CreateTask (), CreateTask (), CreateTask (), creat ETask (), CreateTask (), CreateTask (), CreateTask (), CreateTask (), CreateTask (), C Reatetask (), CreateTask (), CreateTask (),) fmt. PRINTLN ("Execute task Asynchronously")//Start executing task if err: = Runner. Start (); Err! = Nil {switch Err {case errtimeout:fmt. Println ("Execution timeout") OS. Exit (1) Case errinterrupt:fmt. Println ("task Interrupted") OS. Exit (2)}} t.Log ("Execution End") T.Log (runner. Geterrs ())}//creates the task to perform Func createtask () func (id int) Error {return func (id int) error {FMT. Printf ("Performing%v tasks \ n", id)//simulating task execution, Sleep//time. Sleep (1 * time. Second) return Nil}}

Execution results

An asynchronous execution task is performing 2 tasks executing a task executing 4 tasks performing 3 tasks performing 6 tasks executing 5 tasks executing 9 tasks doing 7 tasks executing 10 tasks executing 13 jobs executing 8 tasks executing 11 tasks Performing 12 task being performed 0 task being carried out by a total of five Service runner_test.go:49: Execution ends runner_test.go:51: [<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]

  

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.