[go学习笔记]二十八、go语言协程之仅需任意任务完成就行!

218 阅读1分钟

示例代码请访问:github.com/wenjianzhan…

任一任务完成就算完成

func runTask(id int) string {
	time.Sleep(10 * time.Millisecond)
	return fmt.Sprintf("The result is from %d\n", id)
}

func FristResponse() string {
	numOfRunner := 10
	ch := make(chan string)
	for i := 0; i < numOfRunner; i++ {
		go func(i int) {
			ret := runTask(i)
			ch <- ret
		}(i)
	}
	return <-ch
}

func TestFristResponse(t *testing.T) {
	t.Log("Before:", runtime.NumGoroutine())
	t.Log(FristResponse())
	time.Sleep(time.Second * 1)
	t.Log("After:", runtime.NumGoroutine())
}

输出

=== RUN   TestFristResponse
--- PASS: TestFristResponse (1.02s)
    frist_response_test.go:28: Before: 2
    frist_response_test.go:29: The result is from 1
        
    frist_response_test.go:31: After: 11
PASS

Process finished with exit code 0

输出信息可以看到执行后还有11哥协程阻塞在哪里,时间长了就会造成资源的耗尽; 我们对程序进行一下调整


func runTask(id int) string {
	time.Sleep(10 * time.Millisecond)
	return fmt.Sprintf("The result is from %d\n", id)
}

func FristResponse() string {
	numOfRunner := 10
	ch := make(chan string,numOfRunner)
	for i := 0; i < numOfRunner; i++ {
		go func(i int) {
			ret := runTask(i)
			ch <- ret
		}(i)
	}
	return <-ch
}

func TestFristResponse(t *testing.T) {
	t.Log("Before:", runtime.NumGoroutine())
	t.Log(FristResponse())
	time.Sleep(time.Second * 1)
	t.Log("After:", runtime.NumGoroutine())
}

输出

=== RUN   TestFristResponse
--- PASS: TestFristResponse (1.01s)
    frist_response_test.go:28: Before: 2
    frist_response_test.go:29: The result is from 0
        
    frist_response_test.go:31: After: 2
PASS

Process finished with exit code 0

现在在看输出结果,执行前和执行后的协程数量是一样的

更多学习笔记和示例代码请访问:github.com/wenjianzhan…

也请大家分享一些自己的问题和经验,共同学习进步