Go并发控制模型

1. Sync

分别使用sync.WaitGroup提供的Add,Done,Wait来控制计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
    "fmt"
    "sync"
)

func main() {
    nameList := [3]string{"zhang san""li si""wang wu"}
    var wg sync.WaitGroup

    wg.Add(len(nameList))
    for _, name := range nameList {
        go func(name string) {
            defer wg.Done()
            fmt.Printf("name: %s \n", name)
        }(name)
    }

    wg.Wait()

    fmt.Println("over")
}

2. Channel

通过channel阻塞实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
    "fmt"
    "sync"
)

func main() {
    nameList := [3]string{"zhang san""li si""wang wu"}

    // channel
    ch := make(chan intlen(nameList))
    for _, name := range nameList {
        go func(name string) {
            ch <- 1
            fmt.Printf("name: %s \n", name)
        }(name)
    }

    // 等待N个后台线程完成
    for i := 0; i < cap(ch); i++ {
        <-ch
    }

    fmt.Println("over")
}

3. Context

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main

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

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    go funcA(ctx)

    time.Sleep(time.Second * 5)
    cancel()
    time.Sleep(time.Second * 5)

    fmt.Println("over")
}

func funcA(ctx context.Context) {
    go funcB(ctx)
    for {
        time.Sleep(time.Second * 1)
        select {
        case <-ctx.Done():
            fmt.Println("funcA Stop")
            return
        default:
            fmt.Println("doing funcA...")
        }
    }
}

func funcB(ctx context.Context) {
    for {
        time.Sleep(time.Second * 1)
        select {
        case <-ctx.Done():
            fmt.Println("funcB Stop")
            return
        default:
            fmt.Println("doing funcB...")
        }
    }
}