## Golang多核判斷素數方式 缺陷: 1. 判斷素數的方法很low,有更好的數學方法降維打擊 2. 結束程式的方式很差,有可能(幾乎必然)漏掉末尾幾個素數無法錄入 ...
## Golang多核判斷素數方式
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "runtime" 8 "strconv" 9 "syscall" 10 ) 11 12 func main() { 13 //開啟真多核 14 runtime.GOMAXPROCS(runtime.NumCPU()) 15 intchan := make(chan int, 10000) //向intchan內寫入若幹個數字,判斷這些數字是否為質數 16 final := make(chan int, 10000) //結果集,質數都放在裡面 17 exitchan := make(chan bool, 5) //當收集到5個true時,程式即可結束 18 19 // 開啟協程,向intchan放入數據(1-10000) 20 go func(intchan chan int) { 21 for i := 2; i <= 10000; i++ { 22 intchan <- i 23 } 24 25 }(intchan) 26 27 //開啟四個正經工作的協程,他們來判斷誰是質數 28 for c := 1; c < 5; c++ { 29 go countprime(intchan, final, exitchan, c) 30 } 31 32 // 從結果集合中寫入文件 33 go func(final chan int, exitchan chan bool) { 34 file, _ := os.OpenFile("prime.txt", syscall.O_APPEND, 1) 35 defer file.Close() 36 defer close(final) 37 writer := bufio.NewWriter(file) 38 n := 500 39 for { 40 num := <-final 41 if num == 10000 { 42 exitchan <- true 43 break 44 } 45 writer.WriteString(strconv.Itoa(num)) 46 writer.WriteString(",") 47 // 多個協程共同工作,所以返回數不是遞增的,所以這種分行方式非常不好用 48 if num > n { 49 writer.WriteString("\n") 50 n = num + 500 51 } 52 writer.Flush() 53 54 } 55 }(final, exitchan) 56 57 // 讀出5個數據後,代表所有協程都工作完畢,可以關閉程式 58 for v := 1; v < 6; v++ { 59 <-exitchan 60 } 61 close(exitchan) 62 fmt.Println("程式結束.") 63 } 64 65 func countprime(intchan chan int, final chan int, exit chan bool, t int) { 66 ISPRIME: 67 for { 68 num, ok := <-intchan 69 if !ok { 70 break 71 } 72 if num == 10000 { 73 final <- 10000 74 close(intchan) 75 break 76 } else { 77 num2 := num 78 for i := 2; i < num2; i++ { 79 //降低時間複雜度,正經判斷素數不用這種方式 80 num2 = num / i 81 if num%i == 0 { 82 continue ISPRIME 83 } 84 } 85 final <- num 86 } 87 } 88 fmt.Println(t, "號協程完成工作") 89 exit <- true 90 }
缺陷:
1. 判斷素數的方法很low,有更好的數學方法降維打擊
2. 結束程式的方式很差,有可能(幾乎必然)漏掉末尾幾個素數無法錄入