Golang并行判断素数

## 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.  结束程序的方式很差,有可能(几乎必然)漏掉末尾几个素数无法录入

猜你喜欢

转载自www.cnblogs.com/GuanTouKnight/p/10279125.html
今日推荐