美文网首页
using context and waitgroup to

using context and waitgroup to

作者: perryn | 来源:发表于2018-04-18 10:08 被阅读18次
    package main
    
    import (
        "context"
        "flag"
        "fmt"
        "math/rand"
        "os"
        "os/signal"
        "sync"
        _ "time"
    )
    
    /*
    
    context:
        1.control goroutine casecade
            ctx,cancel := context.WithCancel(ctx)
            go A(ctx)
            go B(ctx)
            go C(ctx)
            defer cancel()
    
    single stop chan:
        1.just controll goroutine less than one,if you start many goroutine,so you should use context to controll
    
    */
    
    var (
        taskCount = flag.Int("count", 2, "task count")
    )
    
    const (
        defaultTaskSize = 1
    )
    
    type Task struct {
        Id int
    }
    
    func NewTask(n int) []*Task {
        if n < defaultTaskSize {
            n = defaultTaskSize
        }
        taskes := make([]*Task, 0, n)
        for i := 0; i < n; i++ {
            task := &Task{Id: rand.Intn(1024)}
            taskes = append(taskes, task)
        }
        return taskes
    }
    func Process(task *Task) {
        fmt.Println("...process task ", task.Id, "...")
    }
    func Work(ctx context.Context, wg *sync.WaitGroup, ch chan *Task) {
        defer wg.Done()
        for {
            select {
            case task := <-ch:
                Process(task)
            case <-ctx.Done():
                fmt.Println("......goroutine exit.....")
                return
            }
        }
    }
    func main() {
        signals := make(chan os.Signal, 1)
        signal.Notify(signals, os.Interrupt)
        flag.Parse()
        count := *taskCount
        ch := make(chan *Task, 3)
        ctx, cancel := context.WithCancel(context.Background())
    
        wg := &sync.WaitGroup{}
        wg.Add(count)
        for i := 0; i < count; i++ {
            go Work(ctx, wg, ch)
        }
        taskes := NewTask(count)
        fmt.Println("....start ", count, " task.....")
        for _, task := range taskes {
            ch <- task
        }
        defer wg.Wait()
        defer cancel()
        // defer call list:  cancel() -> wg.Wait()
        for {
            select {
            case <-signals:
                fmt.Println("...recv main stop....")
                return
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:using context and waitgroup to

          本文链接:https://www.haomeiwen.com/subject/eexvkftx.html