乐趣区

关于golang:golang-并发编程总结

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func main() {}

//
// 例子中咱们通过 select 判断 stop 是否承受到值,如果承受到值就示意能够推出进行了,如果没有承受到,// 就会执行 default 外面的监控逻辑,持续监控,直到收到 stop 的告诉
// 以上管制 goroutine 的形式在大多数状况下能够满足咱们的应用,然而也存在很多局限性,比方有很多 goroutiine,// 并且这些 goroutine 还衍生了其余 goroutine,此时 chan 就比拟艰难解决这样的问题了
func testChan() {stop := make(chan bool)
    go func() {
        for {
            select {
            case <-stop:
                fmt.Println("")
                return
            default:
                fmt.Println("groutine 监控中...")
                time.Sleep(1 * time.Second)
            }
        }
    }()
    time.Sleep(10 * time.Second)
    fmt.Println("能够了, 监控进行了")
    stop <- true
    time.Sleep(5 * time.Second)
}

// 以上例子肯定要等到两个 goroutine 同时做完才会全副实现,这种管制并发形式尤其实用于多个 goroutine 协同做一件事件的时候。func testWaitGroup() {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {defer wg.Done()
        time.Sleep(2 * time.Second)
    }()

    go func() {defer wg.Done()
        time.Sleep(3 * time.Second)
    }()
    wg.Wait()
    fmt.Println("好了,大家都干完活了")
}

func CancelTest() {ctx, cancel := context.WithCancel(context.Background())
    go func(ctx context.Context) {
        for {
            select {case <-ctx.Done():
                fmt.Println("协程退出,进行了...")
                return
            default:
                fmt.Println("协程运行中...")
                time.Sleep(2 * time.Second)
            }
        }
    }(ctx)
    time.Sleep(time.Second * 30)
    fmt.Println("两分钟工夫到了,敞开子协程")
    cancel()
    time.Sleep(time.Second * 10)
    fmt.Println("演示完结")
}

// TimeOutTest WithTimeout
func TimeOutTest() {ctx, _ := context.WithTimeout(context.Background(), time.Minute*1)
    go func(ctx context.Context) {
        for {
            select {case <-ctx.Done():
                fmt.Println("协程退出,进行了...")
                return
            default:
                fmt.Println("协程运行中...")
                time.Sleep(2 * time.Second)
            }
        }
    }(ctx)
    time.Sleep(time.Second * 70)
    fmt.Println("演示完结")
}

// DeadLineTest WithDeadline
func DeadLineTest() {ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Minute*1))
    go func(ctx context.Context) {
        for {
            select {case <-ctx.Done():
                fmt.Println("协程退出,进行了...")
                return
            default:
                fmt.Println("协程运行中...")
                time.Sleep(2 * time.Second)
            }
        }
    }(ctx)
    time.Sleep(time.Second * 70)
    fmt.Println("演示完结")
}

// WithValueTest WithCancel
func WithValueTest() {ctx, cancel := context.WithCancel(context.Background())
    // 附加值
    valueCtx := context.WithValue(ctx, "test", "子协程 1")
    go func(ctx context.Context) {
        for {
            select {case <-ctx.Done():
                // 取出值
                fmt.Println(ctx.Value("test"), "监控退出,进行了...")
                return
            default:
                // 取出值
                fmt.Println(ctx.Value("test"), "goroutine 监控中...")
                time.Sleep(2 * time.Second)
            }
        }
    }(valueCtx)
    time.Sleep(10 * time.Second)
    fmt.Println("能够了,告诉监控进行")
    cancel()
    // 为了检测监控过是否进行,如果没有监控输入,就示意进行了
    time.Sleep(5 * time.Second)
}
退出移动版