golang — Управление параллелизмом через массивы и каналы через семафоры

package main

import (
	"context"
	"fmt"
	"golang.org/x/sync/semaphore"
	"sync"
)

func doSomething(u string) { // 模拟抓取任务的执行
	//time.Sleep(2 * time.Second)
	fmt.Println(u)

}

const (
	Limit  = 2 // 同時并行运行的goroutine上限
	Weight = 1 // 每个goroutine获取信号量资源的权重
)

var TeshChannel = make(chan int, 1000) // 定义一个带缓冲的channel

func traversalArr(datas []string) {
	s := semaphore.NewWeighted(Limit)
	var w sync.WaitGroup
	for _, u := range datas {
		w.Add(1)
		go func(u string) {
			err := s.Acquire(context.Background(), Weight)
			if err != nil {
				fmt.Println(err)
			}
			doSomething(u)
			s.Release(Weight)
			w.Done()
		}(u)
	}
	w.Wait()
}

func traversalChannel() {
	s := semaphore.NewWeighted(Limit)
	var w sync.WaitGroup
	for u := range TeshChannel {
		w.Add(1)
		go func(u int) {
			//fmt.Println("traversal num: ", u)
			err := s.Acquire(context.Background(), Weight)
			if err != nil {
				fmt.Println(err)
			}
			//doSomething(strconv.Itoa(u))
			doSomething(fmt.Sprintf("this is %d", u))
			s.Release(Weight)
			w.Done()
		}(u)
	}
	w.Wait()
}

func main() {
	// arr test
	urls := []string{
		"http://www.example.com",
		"http://www.example.net",
		"http://www.example.net/foo",
		"http://www.example.net/bar",
		"http://www.example.net/baz",
	}
	traversalArr(urls)
	fmt.Println("Arr Test Done")

	// channel test
	for i := 1; i <= 10; i++ {
		fmt.Println("input chan: ", i)
		TeshChannel <- i
	}
	close(TeshChannel)
	traversalChannel()  // TODO 疑问,调用该方法,打印出来的是无序的?
	fmt.Println("Channel Test Done")

	fmt.Println("All Done")

}

Guess you like

Origin blog.csdn.net/xuezhangjun0121/article/details/132714234