(四十四)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 ...
随机推荐
- Asp.net Core全局异常监控和记录日志
前言 系统异常监控可以说是重中之重,系统不可能一直运行良好,开发和运维也不可能24小时盯着系统,系统抛异常后我们应当在第一时间收到异常信息.在Asp.net Core里我使用拦截器 ...
- day26作业
1.整理TCP三次握手.四次挥手图 2.基于TCP开发一款远程CMD程序 客户端连接服务器后,可以向服务器发送命令 服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端 注意 ...
- ElasticSearch head插件安装与配置
下载 下载地址:https://github.com/mobz/elasticsearch-head 安装 1. 下载到本地 git clone 2. 安装 grunt npm install -g ...
- Node配合WebSocket做多文件下载以及进度回传
起因 为什么做这个东西,是突然间听一后端同事说起Annie这个东西,发现这个东西下载视频挺方便的,会自动爬取网页中的视频,然后整理成列表.发现用命令执行之后是下面的样子: 心里琢磨了下,整一个界面玩一 ...
- MIT线性代数:17.正交矩阵和Cram-Schmidt正交化
- RabbitMQ-交换机模式
在说正题之前先解释一下交换机模式是个笼统的称呼,它不是一个单独的模式(包括了订阅模式,路由模式和主题模式),交换机模式是一个比较常用的模式,主要是为了实现数据的同步. 首先,说一下订阅模式,就和字面上 ...
- it公司比较
1:本人西电通院2013届毕业硕士,根据今年找工作的情况以及身边同学的汇总,总结各大公司的待遇如下,吐血奉献给各位学弟学妹,公司比较全,你想去的公司不在这里面,基本上是无名小公司了:但无名小公司有时也 ...
- Medium高赞系列,如何正确的在Stack Overflow提问
在我们写程序的时候,经常会遇到各色各样的问题,在国内,小伙伴们经常去知乎.CSDN.博客园.思否.安卓巴士等地方提问并获得答案. 这些地方汇集了很多优秀的.爱分享的国内资源.小编比较自豪的一件事情就是 ...
- jquery手指触摸滑动放大图片的方法(比较靠谱的方法)
jquery手指触摸滑动放大图片的方法(比较靠谱的方法) <pre><!DOCTYPE html><html lang="zh-cn">< ...
- jquery layui的巨坑
jquery layui的巨坑 layui 模块不能写在ajax里 因为 layui只能执行一次 第二次会没效果 再执行需要刷新页面再执行