> For the complete documentation index, see [llms.txt](https://gocompiler.shizhz.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gocompiler.shizhz.me/10.-golang-bian-yi-qi-han-shu-bian-yi-ji-dao-chu/10.2.3-bing-fa-kong-zhi.md).

# 10.2.3 并发控制

函数是编译器的编译单元，也是编译器的并发单元，可以通过编译参数 `-c` 指定编译器编译的并发数量。并发控制的代码如下：

```go
func compileFunctions() {
    if len(compilequeue) == 0 {
        return
    }

    // 控制编译顺序
    if race.Enabled {
        // Randomize compilation order to try to shake out races.
        tmp := make([]*ir.Func, len(compilequeue))
        perm := rand.Perm(len(compilequeue))
        for i, v := range perm {
            tmp[v] = compilequeue[i]
        }
        copy(compilequeue, tmp)
    } else {
        // Compile the longest functions first,
        // since they're most likely to be the slowest.
        // This helps avoid stragglers.
        sort.Slice(compilequeue, func(i, j int) bool {
            return len(compilequeue[i].Body) > len(compilequeue[j].Body)
        })
    }

    // We queue up a goroutine per function that needs to be
    // compiled, but require them to grab an available worker ID
    // before doing any substantial work to limit parallelism.
    workerIDs := make(chan int, base.Flag.LowerC)
    for i := 0; i < base.Flag.LowerC; i++ {
        workerIDs <- i
    }

    var wg sync.WaitGroup
    var asyncCompile func(*ir.Func)
    asyncCompile = func(fn *ir.Func) {
        wg.Add(1)
        go func() {
            worker := <-workerIDs
            ssagen.Compile(fn, worker)
            workerIDs <- worker

            // Done compiling fn. Schedule it's closures for compilation.
            for _, closure := range fn.Closures {
                asyncCompile(closure)
            }
            wg.Done()
        }()
    }

    types.CalcSizeDisabled = true // not safe to calculate sizes concurrently
    base.Ctxt.InParallel = true
    for _, fn := range compilequeue {
        asyncCompile(fn)
    }
    compilequeue = nil
    wg.Wait()
    base.Ctxt.InParallel = false
    types.CalcSizeDisabled = false
}
```

可见 `-c` 控制并发数量，然后函数 `asyncCompile` 通过 `workerIDs` 与 `sync.WaitGroup` 进行并发同步。
