欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Golang并行判断素数

程序员文章站 2022-07-05 15:40:37
## 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.  结束程序的方式很差,有可能(几乎必然)漏掉末尾几个素数无法录入