Contents

Go conc

Contents

Go conc

参考链接

go

package main

import (
	"fmt"
	"time"
)

func main() {

	for i := 0; i < 5; i++ {
		go func(num int) {
			fmt.Println(num)
		}(i)
	}

	time.Sleep(5 * time.Second)
}

sync.WaitGroup 控制并发

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func hello(i int) {
	defer wg.Done() 
	fmt.Println("Hello Goroutine!", i)
}

func main() {

	for i := 0; i < 10; i++ {
		wg.Add(1) 
		go hello(i)
	}
	wg.Wait() 
}

conc 并发库

优点:

  • 封装了官方库的wg.Add和wg.Done,简化了代码
  • 官方库需要手动实现recover,conc 内部封装好了
package main

import (
	"fmt"

	"github.com/sourcegraph/conc"
)

func main() {
	wg := conc.NewWaitGroup()
	for i := 0; i < 10; i++ {
		wg.Go(doSomething)
	}
	wg.Wait()
}

func doSomething() {
	fmt.Println("test")
}

并发池限制

package main

import (
	"fmt"

	"github.com/sourcegraph/conc/pool"
)

func main() {
	p := pool.New().WithMaxGoroutines(3)
	for i := 1; i <= 5; i++ {
		p.Go(func() {
			fmt.Println(i)
		})
	}
	p.Wait()
}
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/sourcegraph/conc/pool"
)

func main() {
	p := pool.New().
		WithMaxGoroutines(4).
		WithContext(context.Background()).
		WithCancelOnError()
	for i := 0; i < 3; i++ {
		i := i
		p.Go(func(ctx context.Context) error {
			if i == 2 {
				return errors.New("I will cancel all other tasks!")
			}
			<-ctx.Done()
			return nil
		})
	}
	err := p.Wait()
	fmt.Println(err)
	// Output:
	// I will cancel all other tasks!
}