为什么我的 goroutine 没有全部执行?需要一个解释
Why not all my goroutines executed? Need an explaination
func main() {
var wg sync.WaitGroup
ch := make(chan int,5)
start:= time.Now()
cnt:=0
wg.Add(10000)
for i:=0; i<10000; i++ {
ch <- 1
go func() {
defer wg.Done()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
这里我想并发执行程序,并且我希望最多有5个goroutines。
问题是当我打印出“cnt”时,它不会是 10000。这意味着我有一些 goroutines 没有被执行。我该如何解决这个问题?
现在我正在使用互斥锁来解决这个问题,但是这个程序的运行-time 并没有用goroutine 更好,我不明白为什么。
func main() {
var wg sync.WaitGroup
var mutex sync.Mutex
ch := make(chan int,5)
start:= time.Now()
cnt:=0
for i:=0; i<10000; i++ {
wg.Add(1)
ch <- 1
go func() {
defer wg.Done()
defer mutex.Unlock()
mutex.Lock()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
在下面的程序中尝试计算工人的数量,看看哪个数字给你最好的结果。虽然,您进行基准测试的方式并不真正可靠,通常应避免使用。
但是这个程序应该运行得更好;肯定有更好的实现。所以在这里你只是产生 workers
数量的 goroutines 但在你的情况下,它是 10000
goroutines 这实际上是没有必要的并且对于小情况;太矫枉过正了。
Note: For me, this program works >50% better than the implementation that you have.
package main
import (
"fmt"
"sync"
"time"
)
type work struct {
wg *sync.WaitGroup
jobs <-chan struct{}
mu *sync.Mutex
val *int
}
// worker is responsible for executing the work assigned
func worker(w work) {
for range w.jobs {
w.mu.Lock()
*w.val++
w.mu.Unlock()
}
w.wg.Done()
}
func main() {
start := time.Now()
jobs := make(chan struct{}, 2) // Number of jobs (buffer)
workers := 2 // Number of workers
cnt := 0 // Shared variable among workers
work := work{
wg: &sync.WaitGroup{},
jobs: jobs,
mu: &sync.Mutex{},
val: &cnt,
}
// Worker Pool
work.wg.Add(workers)
for i := 0; i < workers; i++ {
go worker(work)
}
// Allocate jobs (Signal worker(s))
for i := 0; i < 10000; i++ {
jobs <- struct{}{}
}
// Ask the workers to stop
close(jobs)
work.wg.Wait()
fmt.Println(cnt)
fmt.Println("End of program: ", time.Since(start))
}
func main() {
var wg sync.WaitGroup
ch := make(chan int,5)
start:= time.Now()
cnt:=0
wg.Add(10000)
for i:=0; i<10000; i++ {
ch <- 1
go func() {
defer wg.Done()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
这里我想并发执行程序,并且我希望最多有5个goroutines。 问题是当我打印出“cnt”时,它不会是 10000。这意味着我有一些 goroutines 没有被执行。我该如何解决这个问题?
现在我正在使用互斥锁来解决这个问题,但是这个程序的运行-time 并没有用goroutine 更好,我不明白为什么。
func main() {
var wg sync.WaitGroup
var mutex sync.Mutex
ch := make(chan int,5)
start:= time.Now()
cnt:=0
for i:=0; i<10000; i++ {
wg.Add(1)
ch <- 1
go func() {
defer wg.Done()
defer mutex.Unlock()
mutex.Lock()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
在下面的程序中尝试计算工人的数量,看看哪个数字给你最好的结果。虽然,您进行基准测试的方式并不真正可靠,通常应避免使用。
但是这个程序应该运行得更好;肯定有更好的实现。所以在这里你只是产生 workers
数量的 goroutines 但在你的情况下,它是 10000
goroutines 这实际上是没有必要的并且对于小情况;太矫枉过正了。
Note: For me, this program works >50% better than the implementation that you have.
package main
import (
"fmt"
"sync"
"time"
)
type work struct {
wg *sync.WaitGroup
jobs <-chan struct{}
mu *sync.Mutex
val *int
}
// worker is responsible for executing the work assigned
func worker(w work) {
for range w.jobs {
w.mu.Lock()
*w.val++
w.mu.Unlock()
}
w.wg.Done()
}
func main() {
start := time.Now()
jobs := make(chan struct{}, 2) // Number of jobs (buffer)
workers := 2 // Number of workers
cnt := 0 // Shared variable among workers
work := work{
wg: &sync.WaitGroup{},
jobs: jobs,
mu: &sync.Mutex{},
val: &cnt,
}
// Worker Pool
work.wg.Add(workers)
for i := 0; i < workers; i++ {
go worker(work)
}
// Allocate jobs (Signal worker(s))
for i := 0; i < 10000; i++ {
jobs <- struct{}{}
}
// Ask the workers to stop
close(jobs)
work.wg.Wait()
fmt.Println(cnt)
fmt.Println("End of program: ", time.Since(start))
}