(四十四)golang--协程(goroutine)和管道(channel)相结合实例
统计1-8000之间的素数。
整体框架:
说明:有五个协程,三个管道。其中一个协程用于写入数字到intChan管道中,另外四个用于取出intChan管道中的数字并判断是否是素数,然后将素数写入到primeChan管道中,最后如果后面四个协程哪一个工作完了,就写入一个true到exit管道中,最后利用循环判断这四个协程是否都完成任务,并退出。
main.go
package main import (
"fmt"
"go_code/project_13/test"
"time"
) func putNum(intChan chan int) {
for i := ; i <= ; i++ {
intChan <- i
}
close(intChan)
} func isPrime(n int) bool {
//这里本来i只需要到int(math.Sqrt(float64(n))),为了计算时间,就直接设置i-n了
for i := ; i <= n; i++ {
if n%i == {
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, )
primeChan := make(chan int, )
exitChan := make(chan bool, )
//记录当前时间
start := time.Now()
//开启一个协程
go putNum(intChan)
//开启四个协程
for i := ; i < ; i++ {
go primeNum(intChan, primeChan, exitChan)
}
//当四个协程都完成任务后,计算消耗时间,并关闭primeChan管道
go func() {
for i := ; i < ; 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 := ; i <= n; i++ {
if n%i == {
return false
}
}
return true
}
func Test() {
start := time.Now()
for i := ; i < ; i++ {
isPrime(i)
}
cost := time.Since(start)
fmt.Printf("传统方法消耗时间为:%s", cost)
}
最后运行一下看看结果。
使用协程的方法的确是要比使用传统的方法要快的,有其是在数据量进一步的增大时。至此,一个管道和协程的实例就算完成了,
(四十四)golang--协程(goroutine)和管道(channel)相结合实例的更多相关文章
- 面试必问:Golang高阶-Golang协程实现原理
引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发) 进程和线程的区别 进程是计 ...
- Golang 协程调度
一.线程模型 N:1模型,N个用户空间线程在1个内核空间线程上运行.优势是上下文切换非常快但是无法利用多核系统的优点. 1:1模型,1个内核空间线程运行一个用户空间线程.这种充分利用了多核系统的优势但 ...
- Golang协程与通道整理
协程goroutine 不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换.Go在底层进行协助实现 涉及系统调用的地方由Go标准库协助释放CPU 总之,不通 ...
- golang协程同步的几种方法
目录 golang协程同步的几种方法 协程概念简要理解 为什么要做同步 协程的几种同步方法 Mutex channel WaitGroup golang协程同步的几种方法 本文简要介绍下go中协程的几 ...
- Python与Golang协程异同
背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...
- Golang协程实现流量统计系统(3)
进程.线程.协程 - 进程:太重 - 线程:上下文切换开销太大 - 协程:轻量级的线程,简洁的并发模式 Golang协程:goroutine Hello world package main impo ...
- NeHe OpenGL教程 第四十四课:3D光晕
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 网站开发进阶(四十四)input type="submit" 和"button"的区别
网站开发进阶(四十四)input type="submit" 和"button"的区别 在一个页面上画一个按钮,有四种办法: 这就是一个按钮.如果你不写ja ...
- Gradle 1.12用户指南翻译——第四十四章. 分发插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
随机推荐
- OptimalSolution(7)--大数据和空间限制
一.布隆过滤器 问题:不安全网页的黑名单包含100亿个黑名单网页,每个网页的URL最多占用64B.现在想要实现一种网页过滤系统,可以根据网页的URL判断该网页是否在黑名单上,如何设计该系统. 要求:允 ...
- AS报错:lambda expressions are not supported at this language level
AS报错:lambda expressions are not supported at this language level 解决方法 打开打开 File --> Project Stuct ...
- Linux安装h2数据库
安装H2数据库,为后面mybatisplus3J集成做铺垫 下载jar包 https://pan.baidu.com/s/1tPZQH5tum1CheDxumcN24g 运行jar包 [root@to ...
- 2019年Unity学习资源指南[精心整理]
前言 进入一个领域,最直接有效的方法就是,寻找相关综述性文章,首先你需要对你入门的领域有个概括性的了解,这些包括: 1.主流的学习社区与网站. 2.该领域的知名大牛与热心分享的从业者. 3.如何有效的 ...
- (IDEA) 搭建Maven并使用Maven打包部署
1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME的环境变量,然后将该变量添加到Path中 备注:必须要有JAVA_HOM ...
- xtrabackup备份原理及流式备份应用
目录 xtrabackup备份原理及流式备份应用 0. 参考文献 1. xtrabackup 安装 2. xtrabackup 备份和恢复原理 2.1 备份阶段(backup) 2.2 准备阶段(pr ...
- java核心编程书上的一个错误
书上说这段代码说明了java对对象不是采用的按引用调用 这明显错了,java还是引用传递,只是把引用对象的变量复制了,互换了x,y所指的对象,对a,b没有影响
- DAY 5 搜索
搜索 开篇: mayan游戏(noip2011 day1 T3) 这道题就是个码量题,老师讲题时淡淡的说写完前两题就花一个半小时了,最后一题不快点打会调不出来,对于一个三个半小时就写两题的蒟蒻来说这. ...
- 持续集成Gitlab CICD Runner&Jenkins
目录 使用Gitlab Runner实现 再要部署的服务器上安装 gitlab runner 下载可执行文件 设置可执行权限权限 创建用户 运行服务 注册 Runner 到gitlab上找到需要用的U ...
- 大数据之路day01_2--记事本与EditPlus编写Hello World并且运行
在上一节我们成功的安装JAVA并且将其环境配置成功,接下来我们来编写第一个java程序——Hello World 1.利用记事本编写代码,利用命令行来编译运行 (1)新建记事本,(文件名).java后 ...