同时运行多个Go协程

huangapple go评论84阅读模式
英文:

Running multiple go routines at the same time

问题

我想要运行多个Go协程。我希望它们都同时启动。我添加了另一个同步等待组(sync waitGroup),并在go协程的开始处添加了一个等待(wait)。然而,这并没有使得所有的go协程同时启动。为了使一些go协程在完全相同的时间开始,我应该怎么做?

package main

import (
	"flag"
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup
	routines := flag.Int("runs", 100, "routines running")
	flag.Parse()

	wg.Add(*routines)

	for i := 0; i < *routines; i++ {
		go func() {
			defer wg.Done()
			t := time.Now()
			fmt.Printf("%s\n", t)
		}()
	}
	fmt.Println("Waiting To Finish")
	wg.Wait()
}

你可以使用time.Sleep函数来实现协程的同时启动。在循环中的每个协程启动之前,添加一个time.Sleep来等待所有协程都准备好,然后一起启动。例如,你可以在for循环中添加以下代码:

for i := 0; i < *routines; i++ {
    time.Sleep(time.Millisecond) // 等待1毫秒
    go func() {
        defer wg.Done()
        t := time.Now()
        fmt.Printf("%s\n", t)
    }()
}

这样,所有的协程将在几乎相同的时间内启动。请注意,由于调度和其他因素的影响,它们可能不会完全同时启动,但它们会非常接近。

英文:

I want to run multiple Go routines. I want them to all start up the same time. I added another sync waitGroup and added a wait inside the start of the go routine. This however did not work to have all the go routine start at the same time. What should I do in order to have a number of go routines to start exactly at the same time?

package main

import (
        &quot;flag&quot;
        &quot;fmt&quot;
        &quot;sync&quot;
        &quot;time&quot;
)

func main() {
     var wg sync.WaitGroup
      routines := flag.Int(&quot;runs&quot;, 100, &quot;routines running&quot;)
      flag.Parse()

      wg.Add(*routines)

      for i := 0; i &lt; *routines; i++ {
              go func() {
                      defer wg.Done()
                      t := time.Now()
                      fmt.Printf(&quot;%s\n&quot;, t)
              }()
      }
      fmt.Println(&quot;Waiting To Finish&quot;)
      wg.Wait()

答案1

得分: 14

你可以让所有的goroutine都在一个通道上阻塞,然后在它们都被调度后关闭该通道:

start := make(chan struct{})

for i := 0; i < *routines; i++ {
	go func() {
		<-start
		defer wg.Done()
		t := time.Now()
		fmt.Printf("%s\n", t)
	}()
}
fmt.Println("starting")
close(start)

这样可以尽可能地接近"完全相同的时间"。但实际上无法保证它们总是精确地同时运行,如果goroutine的数量超过了GOMAXPROCS或CPU核心数,它们就不可能完全同时运行。

英文:

You can have all goroutines block on a channel, and close that channel once they are all dispatched:

start := make(chan struct{})

for i := 0; i &lt; *routines; i++ {
	go func() {
		&lt;-start
		defer wg.Done()
		t := time.Now()
		fmt.Printf(&quot;%s\n&quot;, t)
	}()
}
fmt.Println(&quot;starting&quot;)
close(start)

This will get you as close to "exactly the same time" as possible. You can't really guarantee that they always run at precisely the same time, and if there are more goroutines than GOMAXPROCS or CPU cores, they can't possibly run at exactly the same time.

huangapple
  • 本文由 发表于 2016年2月6日 06:16:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/35234503.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定