为什么我的 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))
}