// 並行素数生成器(素数の篩) // // 参考: // Go言語チュートリアル(part10) // http://golang.jp/2009/11/198 // https://play.golang.org/p/9U22NfrXeq // // 変更箇所: // 終了処理追加等 package main import "fmt" import "time" import "runtime" // 自然数をchに送信、またはescから終了信号を受信 func Generator(ch chan<- int, esc <-chan bool, cmp chan<- bool) { LOOP: for i := 2; ; i++ { select { case ch <- i: // iをチャネルchに送信 case <-esc: break LOOP } } cmp <- true // 全てのgoroutineの終了完了送信 } // 受信した値が割り切れない場合は送信 func Filter(ch <-chan int, ch1 chan<- int, esc chan<- bool, esc1 <-chan bool, prime int) { LOOP: for { select { case i := <-ch: // 素数候補値の受信 if i%prime != 0 { select { case ch1 <- i: // 素数候補値の送信 case <-esc1: // 終了信号の受信 break LOOP } } case <-esc1: // 終了信号の受信 break LOOP } } esc <- true // 終了信号の送信 } // 素数生成 Main func main() { // CPU数入力 cpus := runtime.NumCPU() var c int fmt.Printf("CPU数(1〜%d)= ", cpus) fmt.Scan(&c) if 0 < c && c <= cpus { cpus = c } else { fmt.Printf("CPU数 -> %d\n", cpus) } runtime.GOMAXPROCS(cpus) // 生成する素数の個数入力 var pmax int fmt.Printf("生成する素数の個数 = ") fmt.Scan(&pmax) start := time.Now(); ch := make(chan int) // チャネルch生成 esc := make(chan bool) // チャネルesc生成 cmp := make(chan bool) // チャネルcmp生成 go Generator(ch, esc, cmp) // 自然数生成器(goroutine)の生成 for i := 0; i < pmax; i++ { prime := <-ch fmt.Printf("%d番目の素数 : %d\n", i+1, prime) ch1 := make(chan int) esc1 := make(chan bool) go Filter(ch, ch1, esc, esc1, prime) ch = ch1 esc = esc1 } esc <- true // 終了信号の送信 <-cmp // 完了信号の受信 fmt.Printf("完了\n") end := time.Now(); fmt.Printf("%f 秒\n",(end.Sub(start)).Seconds()) }