Created
July 19, 2023 07:56
-
-
Save A-725-K/df73293638a2ea1a89c5b8b383c09d70 to your computer and use it in GitHub Desktop.
eureka-about-golang-channels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"time" | |
"flag" | |
) | |
const ( | |
N = 5 | |
T_MIN = 1 | |
T_MAX = 5 | |
) | |
var P int | |
type Res struct { | |
id int | |
timestamp time.Time | |
} | |
func worker(numCh chan int, standingCh chan Res, workerIdx int) { | |
for { | |
randN := rand.Intn(100) | |
numCh <- randN | |
if randN <= P { | |
break | |
} | |
t := time.Duration(rand.Intn(T_MAX - T_MIN + 1) + T_MIN) | |
time.Sleep(t * time.Second) | |
} | |
standingCh <- Res{workerIdx, time.Now()} | |
close(numCh) | |
} | |
func printCh(chIdx, randN int) { | |
var msg string | |
if randN <= P { | |
msg = fmt.Sprintf("Channel %d: OK ==> [%d] ----------", chIdx, randN) | |
} else { | |
msg = fmt.Sprintf("Channel %d: continue (%d)...", chIdx, randN) | |
} | |
fmt.Println(msg) | |
} | |
func main() { | |
rand.Seed(time.Now().UnixNano()) | |
flag.IntVar(&P, "p", 20, "Probability of success") | |
flag.Parse() | |
standingCh := make(chan Res, N) | |
numChs := []chan int{} | |
for i := 0; i < N; i++ { | |
numChs = append(numChs, make(chan int)) | |
} | |
fmt.Printf("Spawning %d workers with p=%d...\n\n", N, P) | |
for i := 0; i < N; i++ { | |
go worker(numChs[i], standingCh, i) | |
} | |
var n0, n1, n2, n3, n4 int | |
ok0, ok1, ok2, ok3, ok4 := true, true, true, true, true | |
var standing []string | |
for len(standing) != N || ok0 || ok1 || ok2 || ok3 || ok4 { | |
select { | |
case n0, ok0 = <-numChs[0]: | |
if ok0 { | |
printCh(0, n0) | |
} | |
case n1, ok1 = <-numChs[1]: | |
if ok1 { | |
printCh(1, n1) | |
} | |
case n2, ok2 = <-numChs[2]: | |
if ok2 { | |
printCh(2, n2) | |
} | |
case n3, ok3 = <-numChs[3]: | |
if ok3 { | |
printCh(3, n3) | |
} | |
case n4, ok4 = <-numChs[4]: | |
if ok4 { | |
printCh(4, n4) | |
} | |
case r := <-standingCh: | |
standing = append(standing, fmt.Sprintf("%d -- %v", r.id, r.timestamp)) | |
} | |
} | |
allDone := !ok0 && !ok1 && !ok2 && !ok3 && !ok4 | |
fmt.Printf("\nEnd of program!\n\n") | |
if allDone { | |
fmt.Println("SUCCESS!") | |
for idx, result := range standing { | |
fmt.Printf("%d) %s\n", idx+1, result) | |
} | |
// For DEBUG purpose | |
// } else { | |
// fmt.Println("FAIL :(") | |
// fmt.Println("n0 =", n0, "n1 =", n1, "n2 =", n2, "n3 =", n3, "n4 =", n4) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment