Skip to content

Instantly share code, notes, and snippets.

@craftslab
Last active February 11, 2024 02:23
Show Gist options
  • Save craftslab/ed14cc36bd0cd313040299722e819273 to your computer and use it in GitHub Desktop.
Save craftslab/ed14cc36bd0cd313040299722e819273 to your computer and use it in GitHub Desktop.
go routine
package main
import (
"fmt"
"strconv"
"sync"
)
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string, 3)
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(wg, cs, i)
}
go monitor(wg, cs)
for item := range cs {
fmt.Println(item)
}
}
func worker(wg *sync.WaitGroup, cs chan string, i int) {
defer wg.Done()
cs <- "worker" + strconv.Itoa(i)
}
func monitor(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
package main
import (
"fmt"
"strconv"
"sync"
)
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string, 3)
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(wg, cs, i)
}
go monitor(wg, cs)
done := make(chan bool, 1)
go printer(cs, done)
<-done
}
func worker(wg *sync.WaitGroup, cs chan string, i int) {
defer wg.Done()
cs <- "worker" + strconv.Itoa(i)
}
func monitor(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
func printer(cs <-chan string, done chan<- bool) {
for item := range cs {
fmt.Println(item)
}
done <- true
}
package main
import (
"context"
"fmt"
"strconv"
"sync"
"time"
)
const (
TIMEOUT = 10 * time.Second
)
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string, 3)
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(wg, cs, i)
}
go monitor(wg, cs)
done := make(chan bool, 1)
go printer(cs, done)
ctx, cancel := context.WithTimeout(context.Background(), TIMEOUT)
defer cancel()
L:
for {
select {
case <-done:
break L
case <-ctx.Done():
break L
}
}
fmt.Println("done.")
}
func worker(wg *sync.WaitGroup, cs chan string, i int) {
defer wg.Done()
cs <- "worker" + strconv.Itoa(i)
}
func monitor(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
func printer(cs <-chan string, done chan<- bool) {
for item := range cs {
fmt.Println(item)
}
done <- true
}
package main
import (
"context"
"errors"
"fmt"
"sync"
)
func search(ctx context.Context, word string) (string, error) {
select {
case <-ctx.Done():
return "", ctx.Err()
default:
if word == "Go" || word == "Java" {
return "", errors.New("Go or Java")
}
return fmt.Sprintf("result: %s", word), nil
}
}
func coSearch(ctx context.Context, words []string) ([]string, error) {
ctx, cancel := context.WithCancelCause(ctx)
defer cancel(nil)
var (
wg = sync.WaitGroup{}
once = sync.Once{}
results = make([]string, len(words))
tokens = make(chan struct{}, 2)
err error
)
for i, word := range words {
tokens <- struct{}{}
wg.Add(1)
go func(word string, i int) {
defer func() {
wg.Done()
<-tokens
}()
result, e := search(ctx, word)
if e != nil {
once.Do(func() {
err = e
cancel(e)
})
return
}
results[i] = result
}(word, i)
}
wg.Wait()
return results, err
}
package main
import (
"context"
"golang.org/x/sync/errgroup"
)
func coSearch(ctx context.Context, words []string) ([]string, error) {
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(10)
results := make([]string, len(words))
for i, word := range words {
i, word := i, word
g.Go(func() error {
result, err := search(ctx, word)
if err != nil {
return err
}
results[i] = result
return nil
})
}
err := g.Wait()
return results, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment