統計1-8000之間的素數。框架
總體框架:spa
說明:有五個協程,三個管道。其中一個協程用於寫入數字到intChan管道中,另外四個用於取出intChan管道中的數字並判斷是不是素數,而後將素數寫入到primeChan管道中,最後若是後面四個協程哪個工做完了,就寫入一個true到exit管道中,最後利用循環判斷這四個協程是否都完成任務,並退出。線程
main.gocode
package main import ( "fmt" "go_code/project_13/test" "time" ) func putNum(intChan chan int) { for i := 1; i <= 80000; i++ { intChan <- i } close(intChan) } func isPrime(n int) bool { //這裏原本i只須要到int(math.Sqrt(float64(n))),爲了計算時間,就直接設置i-n了 for i := 2; i <= n; i++ { if n%i == 0 { return false } } return true } func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) { for { // time.Sleep(time.Millisecond * 10) num, ok := <-intChan if !ok { break } isp := isPrime(num) if !isp { continue } else { primeChan <- num } } fmt.Println("有一個協程取不到數據而退出了") exitChan <- true } func main() { intChan := make(chan int, 1000) primeChan := make(chan int, 20000) exitChan := make(chan bool, 4) //記錄當前時間 start := time.Now() //開啓一個協程 go putNum(intChan) //開啓四個協程 for i := 0; i < 4; i++ { go primeNum(intChan, primeChan, exitChan) } //當四個協程都完成任務後,計算消耗時間,並關閉primeChan管道 go func() { for i := 0; i < 4; i++ { <-exitChan } cost := time.Since(start) fmt.Printf("使用協程耗費時間:%s\n", cost) close(primeChan) }() for { // res, ok := <-primeChan _, ok := <-primeChan if !ok { break } //在這裏計算已經完成了,爲了計算時間,註釋掉了打印的操做 // fmt.Printf("素數=%d\n", res) } fmt.Println("主線程退出") test.Test() }
test.go協程
package test import ( "fmt" "time" ) func isPrime(n int) bool { for i := 2; i <= n; i++ { if n%i == 0 { return false } } return true } func Test() { start := time.Now() for i := 1; i < 80000; i++ { isPrime(i) } cost := time.Since(start) fmt.Printf("傳統方法消耗時間爲:%s", cost) }
最後運行一下看看結果。blog
使用協程的方法的確是要比使用傳統的方法要快的,有其是在數據量進一步的增大時。至此,一個管道和協程的實例就算完成了, it