Skip to content

Instantly share code, notes, and snippets.

@fujimaki-k
Created May 3, 2023 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fujimaki-k/26b7e6c51b2b6356bbd027e6fc2e9a1b to your computer and use it in GitHub Desktop.
Save fujimaki-k/26b7e6c51b2b6356bbd027e6fc2e9a1b to your computer and use it in GitHub Desktop.
Concurrent example
package main
import (
"errors"
"fmt"
"runtime"
"sync"
)
// Concurrent is concurrently execute tasks for number of CPUs.
func Concurrent(items chan any, task func(any)) {
WithN(runtime.NumCPU(), items, task)
}
// WithN is concurrently execute tasks for number of threads.
func WithN(threads int, items chan any, task func(any)) {
if len(items) < 1 {
return
}
if len(items) < threads || threads < 0 {
threads = len(items)
}
var wg sync.WaitGroup
wg.Add(len(items))
for i := 0; i < threads; i++ {
execute(&wg, items, task)
}
wg.Wait()
}
// Execute is execute task in goroutine.
func execute(wg *sync.WaitGroup, items chan any, task func(any)) {
go func() {
for value := range items {
task(value)
wg.Done()
}
}()
}
func main() {
values := []string{"Honoka", "Kotori", "Umi", "Maki", "Rin", "Hanayo", "Nico", "Nozomi", "Eli"}
items := make(chan any, len(values))
defer close(items)
for _, value := range values {
items <- value
}
rejects := make(chan error, len(values))
defer close(rejects)
Concurrent(items, func(value any) {
if value == "Honoka" || value == "Kotori" || value == "Hanayo" {
rejects <- errors.New("fight dayo!")
return
}
fmt.Println(value)
})
for {
select {
case err := <-rejects:
fmt.Println(err)
default:
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment