package main
import (
"fmt"
"math"
"runtime"
"strconv"
"strings"
"time"
)
func producer(intChan chan int) {
for b := 1000; b <= 1099; b++ {
intChan <- b
}
close(intChan)
}
func consumer(intChan chan int, primeChan chan int, exitChan chan bool) {
var b, ok, flag = 0, true, true
var lastNumber int
for {
lastNumber = b
b, ok = <-intChan
if !ok {
exitChan <- true
break
}
flag = true
for v := 2; v < int(math.Sqrt(float64(b)))+1; v++ {
time.Sleep(time.Millisecond * 30)
if b%v == 0 {
flag = false
break
}
}
if flag {
primeChan <- b
}
}
fmt.Printf("Goroutine(%03v) exit, last number: %v\n", GetGoroutineID(), lastNumber)
}
func main() {
intChan := make(chan int, 100)
primeChan := make(chan int, 2000)
exitChan := make(chan bool, 4)
go producer(intChan)
for i := 0; i < cap(exitChan); i++ {
go consumer(intChan, primeChan, exitChan)
}
go func() {
for i := 0; i < cap(exitChan); i++ {
<-exitChan
}
close(exitChan)
close(primeChan)
}()
for {
v, ok := <-primeChan
if !ok {
break
}
fmt.Printf("Prime: %v\n", v)
}
fmt.Printf("main Goroutine(%v) exit", GetGoroutineID())
}
func GetGoroutineID() int {
var buf = make([]byte, 128)
b := runtime.Stack(buf, false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:b]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}