mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
package task
|
|
|
|
import (
|
|
"runtime"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
// ParallelForN runs fn(0..n-1) in parallel across runtime.GOMAXPROCS(0) worker
|
|
// goroutines. Indices are partitioned into contiguous chunks so the number of
|
|
// spawned goroutines stays bounded regardless of n.
|
|
//
|
|
// fn must be safe to call concurrently from different goroutines (each call
|
|
// receives its own unique index). Output collected by writing to indexed slots
|
|
// in a pre-allocated slice is a common safe pattern.
|
|
//
|
|
// Returns the first non-nil error reported by fn; other workers may still be
|
|
// finishing briefly afterwards.
|
|
func ParallelForN(n int, fn func(i int) error) error {
|
|
if n <= 0 {
|
|
return nil
|
|
}
|
|
workers := max(runtime.GOMAXPROCS(0), 1)
|
|
workers = min(workers, n)
|
|
chunk := (n + workers - 1) / workers
|
|
var eg errgroup.Group
|
|
for w := range workers {
|
|
start := w * chunk
|
|
end := min(start+chunk, n)
|
|
if start >= end {
|
|
break
|
|
}
|
|
eg.Go(func() error {
|
|
for i := start; i < end; i++ {
|
|
if err := fn(i); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
return eg.Wait()
|
|
}
|