Go并发编程
一、goroutine 和 通道
在Go语言中,每一个并发执行的活动成为goroutine。通道则是每一个goroutine之间传递消息的工具。
1、Goroutine
在一个Go程序中,只有一个主Goroutine来调用main函数。生成新的goroutine也十分简单,例如有一个函数:f(), 只需在其前面加上go关键字即可将其作为并发程序执行。
例:
package mainimport ("fmt""time"
)func main() {n := 5//开启goroutinego f(n)for i := 0; i < n; i++ {fmt.Println("I am goroutine main()")time.Sleep(50 * time.Millisecond)}
}func f(n int) {for i := 0; i < n; i++ {fmt.Println("I am goroutine f()")time.Sleep(50 * time.Millisecond)}
}// sout:
// I am goroutine main()
// I am goroutine f()
// I am goroutine f()
// I am goroutine main()
// I am goroutine main()
// I am goroutine f()
// I am goroutine f()
// I am goroutine main()
// I am goroutine main()
// I am goroutine f()
虽然Go语言实现并发十分方便,但是如何实现goroutine之间的通信以及保证并发的安全性依然是一件有挑战的事。
2、通道(chan)
通道是goroutine之间的连接,让特定的值在各个goroutine之间传递。
使用make函数创建一个通道:ch := make(chan type, cap). type为ch传递值的类型,cap为通道的大小(同时能容纳多少值),type可以为任意类型。
通道对应操作(都存在阻塞):
- 发送 ( c h < − x ch<-x ch<−x) x为对应类型的变量,ch为通道。(ch满了会存在阻塞)
- 接受( x < − c h x<-ch x<−ch)x为对应类型的变量,ch为通道。(ch空了会存在阻塞)
- 关闭通道close(ch)(ch发送操作被禁止,接受操作被释放)
无缓冲通道: 通道只有一个元素,接受方和发送方会相互阻塞。
管道: 通道有多个chan元素,用来连接不同的goroutine,一个chan的输入是另一个chan的输入。
单向通道类型: 类型( c h a n < − i n t chan<-int chan<−int)为只能发送的通道,类型( < − c h a n i n t <-chan int <−chanint)为只能接收的int类型通道。
缓冲通道: 有一个元素队列,一个cap大于1的通道类型。
注意细节:
- chan变量默认值为nil,使用’=='时若二者是同一通道数据的引用时返回true。
- 若关闭后还有写操作会发生宕机panic,读取其零值故可将其作为开关使用。
- 操作 x,ok := <-ch (x为读取的值,ok为bool值,当ch被close时会返回false,故可以使用range来获取ch的值直到ch被close)。
- select开关操作(关闭某一服务),利用select捕获通道关闭的信息,从而关闭对应的服务。
例:
done := make(chan struct{})go func() {os.Stdin.Read(make([]byte, 1))close(done)}()loop:for {select {//捕获是否关闭。case <-done:fmt.Println("program end!")break loopdefault:fmt.Println("program runing!")}time.Sleep(1 * time.Second)}
一个爬虫案例,使用bfs方式爬取一个网页的所有url:
package gorunimport ("fmt""log""net/http""golang.org/x/net/html"
)func Catch() {//通道用来在goroutine之间传递结果worklist := make(chan []string)//计数器用来判断结束状态,关闭goroutinecnt := 0go func() {worklist <- []string{"http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/person/person_home.html"}}()cnt++//标记已遍历的url,防止重复的url被读取seen := make(map[string]bool)for ; cnt > 0; cnt-- {list := <-worklistfor _, link := range list {if !seen[link] {seen[link] = truecnt++//慢函数,用新的goroutine执行,提高效率。go func(link string) {//该处会不停地生成新的goroutineworklist <- crawl(link)}(link)}}}
}
//chan变量,利用其阻塞的特性,用于控制新增goroutine的数量
var token = make(chan struct{}, 20)// 在生成goroutine时做限制,控制生成的goroutine的数量
func crawl(url string) []string {fmt.Println(url)//获取token <- struct{}{}list, err := extract(url)//释放defer func() {<-token}()if err != nil {log.Println(err)}return list
}//分析网页中的html文件,搜索其中的url
func extract(url string) ([]string, error) {resp, err := http.Get(url)if err != nil {return nil, err}if resp.StatusCode != http.StatusOK {resp.Body.Close()return nil, fmt.Errorf("getting %s: %s", url, resp.Status)}doc, err := html.Parse(resp.Body)resp.Body.Close()if err != nil {return nil, fmt.Errorf("parse %s as html: %v", url, err)}var links []stringvisitNode := func(n *html.Node) {if n.Type == html.ElementNode && n.Data == "a" {for _, a := range n.Attr {if a.Key != "href" {continue}link, err := resp.Request.URL.Parse(a.Val)if err != nil {continue}links = append(links, link.String())}}}forEachNode(doc, visitNode, nil)return links, nil
}func forEachNode(n *html.Node, pre, post func(n *html.Node)) {if pre != nil {pre(n)}for c := n.FirstChild; c != nil; c = c.NextSibling {forEachNode(c, pre, post)}if post != nil {post(n)}
}
相关文章:
Go并发编程
一、goroutine 和 通道 在Go语言中,每一个并发执行的活动成为goroutine。通道则是每一个goroutine之间传递消息的工具。 1、Goroutine 在一个Go程序中,只有一个主Goroutine来调用main函数。生成新的goroutine也十分简单,例如有一个函数&…...
Nignx及负载均衡动静分离
核心要点:部署后台项目 1.配置jdk环境 1.先将jdk的Linux版本的压缩包上传虚拟机中服务器 2.解压上传的jdk压缩包 tar -zxvf jdk.gz 3.先进入jdk的解压目录,再通过pwd查看当前解压包的路径 4.将 解压包路径 配置到 /etc/profile 5…...
HDFS架构介绍
数新网络_让每个人享受数据的价值浙江数新网络有限公司是一家开源开放、专注于云数据智能操作系统和数据价值流通的服务商。公司自主研发的DataCyber云数据智能操作系统,主要包括数据平台CyberData、人工智能平台CyberAI、数据智能引擎CyberEngine、数据安全平台Cyb…...
微信小程序提示确认框 wx.showModal
核心实现代码如下 wx.showModal({ title: 确认, content: 确定要删除吗?, success (res) { if (res.confirm) { console.log(用户点击确定) } else if (res.cancel) { console.log(用户点击取消) } } })title 是确认框的标题,content 是确认…...
如何设置OBS虚拟摄像头给钉钉视频会议使用
环境: OBS Studio 29.1.3 Win10 专业版 钉钉7.1.0 问题描述: 如何设置OBS虚拟摄像头给钉钉视频会议使用 解决方案: 1.打开OBS 底下来源这添加视频采集设备 选择OBS虚拟摄像头 2.源那再建一个图像,随便选一张图片 3.点击虚…...
SpringCloud 微服务全栈体系(十一)
第十章 RabbitMQ 三、SpringAMQP SpringAMQP 是基于 RabbitMQ 封装的一套模板,并且还利用 SpringBoot 对其实现了自动装配,使用起来非常方便。 SpringAmqp 的官方地址:https://spring.io/projects/spring-amqp SpringAMQP 提供了三个功能&…...
45基于matlab的ARIMA:AutoregressiveIntegratedMovingAverage model。
基于matlab的ARIMA:AutoregressiveIntegratedMovingAverage model。自回归差分移动平均模型(p,d,q),AR自回归模型,MA移动平均模型,时间序列模型步骤包括:1. 数据平稳性检验;2. 确定模型参数;3. …...
2010年408计网
下列选项中, 不属于网络体系结构所描述的内容是(C)A. 网络的层次B. 每层使用的协议C. 协议的内部实现细节D. 每层必须完成的功能 本题考查网络体系结构的相关概念 再来看当今世界最大的互联网,也就是因特网。它所采用的TCP/IP 4层网络体系结…...
初谈Linux-Linux环境搭建(阿里云免费服务器+xshell)
文章目录 前言Linux环境搭建结尾 前言 Linux is not unix 本篇文章小编初谈Linux并搭建Linux环境(阿里云免费服务器shell) Linux Linux是一个开源的操作系统 环境搭建 1.点击阿里云ECS免费学生服务器 2.注册后完成学生认证 3.购买云服务器…...
如何利用AppScan扫描H5页面,进行安全测试?
前期项目组接触的都是Web安全测试,今天做安全测试的时候,有一个项目刚好有H5页面,用以前那种AppScan内置浏览器的探索方式是不行的,研究了下,可以使用外部设备进行探索。 AppScan有两种手动探索方式,一种是…...
Oracle数据库中的table@xyz是什么意思?
是DBlink访问外部表的语法。xyz是其他Oracle数据库在你所登录的用户下建立的Dblink名。通过这种方式访问其他数据库中的表。 在Oracle数据库中,表名后跟着符号和一个连接字符串(xyz)是一种用法,它用于指定要访问的远程数据库。 …...
springboot常见网络相关错误及原因解析
在基于spring-boot开发过程尤其是上线后,经常出现网络相关的错误,令人难以琢磨和下手,所以就spring-boot使用过程中可能碰到的网络相关问题进行分析,结合网络转包、日志报错和前端输出,针对网络连接超时、连接被拒绝、…...
【C语言_线程pthread_互斥锁mutex_条件触发cond 之解析与示例 (开源)】.md updata:23/11/03
文章目录 线程 pthread线程 vs 进程线程退出 等待 消息传递join:等待,传参void*; exit:退出,对参数赋值void**; 互斥锁 mutex互斥锁mutex条件cond_等待wait、触发signal 控制线程执行 补充: 宏-静态初始化 互斥锁/条件 线程 pthread 线程 vs…...
mongodb如何删除数据并释放空间
mongodb删除数据后不会直接释放内存空间,是因为使用了一种称为“延迟删除”的策略。这意味着当一个文档被删除时,它仍然会占用一定的内存空间,直到这个空间被垃圾回收器(Garbage Collector)回收。 删除数据操作前建议先…...
k8s之集群调度
目录 调度 工作机制 调度过程 调度算法 优先级 指定调度节点 调度 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件,向 APIServer 发送命令…...
代码随想录算法训练营第四十二天丨 动态规划part05
1049.最后一块石头的重量II 思路 本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。 感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。 本题物品的重量为 stones[i],物品的价…...
[css] flex 子元素自动撑开父元素宽度
对于水平排列的情况,我们可以设置父元素的flex-direction属性为row。这样,子元素将会水平排列在一行内,并自动撑开父元素的宽度。如果子元素的宽度总和超过了父元素的宽度,则子元素会被压缩,以适应父元素的宽度。 对于…...
全新干货!一招教你迅速提升流量主收入!包你轻松月入过万
也不怕大家笑话,才哥以前收入每天才一块钱,连瓶水都买不了, 可是自从我开始接触老年粉私域后,一个搬运公众号的流量主收益两个月后就可以用“浴火重生”来形容了。 一个搬运公众号一天的流量主收益比我原创两年的个人公众号收益还…...
连接两个dataframe
concat import pandas as pd df1 pd.DataFrame({‘A’: [1, 2, 3], ‘B’: [4, 5, 6]}) df2 pd.DataFrame({‘A’: [7, 8, 9], ‘B’: [10, 11, 12]}) result pd.concat([df1, df2]) # 在行上连接 merge import pandas as pd df1 pd.DataFrame({‘key’: [‘A’, ‘B…...
【入门Flink】- 05Flink运行时架构以及一些核心概念
系统架构 Flink运行时架构Standalone会话模式为例 1)作业管理器(JobManager) JobManager 是一个 Flink 集群中任务管理和调度的核心,是控制应用执行的主进程。每个应用都应该被唯一的 JobManager 所控制执行。 JobManger 又包含…...
现代化管理平台架构优化:FastAPI+Vue3+RBAC权限模型的技术实现与性能提升
现代化管理平台架构优化:FastAPIVue3RBAC权限模型的技术实现与性能提升 【免费下载链接】vue-fastapi-admin ⭐️ 基于 FastAPIVue3Naive UI 的现代化轻量管理平台 A modern and lightweight management platform based on FastAPI, Vue3, and Naive UI. 项目地址…...
别再乱接线了!12V手电钻保护板(B+/B-/B1/B2)保姆级接线图解,附万用表检测电池坏点技巧
12V手电钻保护板接线全攻略:从原理到实战的安全操作指南 面对手电钻保护板上密密麻麻的接线端子,即使是经验丰富的DIY爱好者也难免感到困惑。B、B-、B1、B2这些看似简单的标记背后,实际上隐藏着锂电池组安全工作的关键机制。本文将带您深入理…...
从模型到代码:无人驾驶轨迹跟踪算法(Stanley、LQR、PID)的Carsim/Simulink联合仿真实践
1. 无人驾驶轨迹跟踪算法入门指南 第一次接触无人驾驶轨迹跟踪算法时,我被各种专业术语搞得晕头转向。直到真正动手在Carsim和Simulink里搭建仿真环境,才明白这些算法到底是怎么运作的。轨迹跟踪算法的核心任务很简单:让车辆按照预定路线行驶…...
仓储AGV“大脑“江湖:这家公司拿下37%市场,却仍亏损1.7亿,还马上冲港股
导语大家好,这里是智能仓储物流技术研习社:专注分享智能制造和智能仓储物流等内容。专业书籍:《智能物流系统构成与技术实践》|《智能仓储项目英语手册》|《智能仓储项目必坑手册》|《智能仓储项目甲方必读》|《12大行业智能仓储实战指南》做…...
Perplexity法律文献搜索实战指南:7步构建精准检索式,避开90%的无效结果
更多请点击: https://codechina.net 第一章:Perplexity法律文献搜索实战指南:7步构建精准检索式,避开90%的无效结果 Perplexity 作为面向专业研究者的AI搜索工具,在法律文献检索中展现出远超通用搜索引擎的语义理解与…...
别再死记硬背!用Python+Verilog双视角图解2ASK/2FSK调制解调原理
PythonVerilog双视角图解2ASK/2FSK调制解调原理 通信工程的学习者常常陷入理论公式与硬件实现之间的认知断层。当教科书上的数学表达式突然变成硬件描述语言时,那种手足无措的感觉我深有体会——三年前第一次接触Verilog实现调制解调时,盯着代码里那些分…...
告别环境配置烦恼:用PHPStudy+VSCode搭建PHP调试环境(含XDebug配置避坑指南)
告别环境配置烦恼:用PHPStudyVSCode搭建PHP调试环境(含XDebug配置避坑指南) 刚接触PHP开发时,最令人头疼的莫过于环境配置。明明跟着教程一步步操作,却总是卡在某个环节无法继续。特别是XDebug调试器的配置,…...
解锁Nintendo Switch游戏备份的终极指南:nxdumptool完全攻略
解锁Nintendo Switch游戏备份的终极指南:nxdumptool完全攻略 【免费下载链接】nxdumptool Generates XCI/NSP/HFS0/ExeFS/RomFS/Certificate/Ticket dumps from Nintendo Switch gamecards and installed SD/eMMC titles. 项目地址: https://gitcode.com/gh_mirro…...
MAA明日方舟自动化工具终极指南:如何用智能助手彻底解放游戏时间
MAA明日方舟自动化工具终极指南:如何用智能助手彻底解放游戏时间 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: h…...
Claude规格说明书生成器:提升大模型任务执行效率的工程化方法
1. 项目概述:一个为Claude模型定制的“规格说明书”生成器如果你和我一样,经常与Anthropic的Claude系列大语言模型打交道,无论是Claude 3 Opus、Sonnet还是Haiku,那你肯定遇到过这样的场景:你有一个复杂的任务…...
