当前位置: 首页 > news >正文

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可以为任意类型。
通道对应操作(都存在阻塞):

  1. 发送 ( c h < − x ch<-x ch<x) x为对应类型的变量,ch为通道。(ch满了会存在阻塞)
  2. 接受( x < − c h x<-ch x<ch)x为对应类型的变量,ch为通道。(ch空了会存在阻塞)
  3. 关闭通道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的通道类型。

注意细节:

  1. chan变量默认值为nil,使用’=='时若二者是同一通道数据的引用时返回true。
  2. 若关闭后还有写操作会发生宕机panic,读取其零值故可将其作为开关使用。
  3. 操作 x,ok := <-ch (x为读取的值,ok为bool值,当ch被close时会返回false,故可以使用range来获取ch的值直到ch被close)。
  4. 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语言中&#xff0c;每一个并发执行的活动成为goroutine。通道则是每一个goroutine之间传递消息的工具。 1、Goroutine 在一个Go程序中&#xff0c;只有一个主Goroutine来调用main函数。生成新的goroutine也十分简单&#xff0c;例如有一个函数&…...

Nignx及负载均衡动静分离

核心要点&#xff1a;部署后台项目 1.配置jdk环境 1.先将jdk的Linux版本的压缩包上传虚拟机中服务器 2.解压上传的jdk压缩包 tar -zxvf jdk.gz 3.先进入jdk的解压目录&#xff0c;再通过pwd查看当前解压包的路径 4.将 解压包路径 配置到 /etc/profile 5…...

HDFS架构介绍

数新网络_让每个人享受数据的价值浙江数新网络有限公司是一家开源开放、专注于云数据智能操作系统和数据价值流通的服务商。公司自主研发的DataCyber云数据智能操作系统&#xff0c;主要包括数据平台CyberData、人工智能平台CyberAI、数据智能引擎CyberEngine、数据安全平台Cyb…...

微信小程序提示确认框 wx.showModal

核心实现代码如下 wx.showModal({ title: 确认, content: 确定要删除吗&#xff1f;, success (res) { if (res.confirm) { console.log(用户点击确定) } else if (res.cancel) { console.log(用户点击取消) } } })title 是确认框的标题&#xff0c;content 是确认…...

如何设置OBS虚拟摄像头给钉钉视频会议使用

环境&#xff1a; OBS Studio 29.1.3 Win10 专业版 钉钉7.1.0 问题描述&#xff1a; 如何设置OBS虚拟摄像头给钉钉视频会议使用 解决方案&#xff1a; 1.打开OBS 底下来源这添加视频采集设备 选择OBS虚拟摄像头 2.源那再建一个图像&#xff0c;随便选一张图片 3.点击虚…...

SpringCloud 微服务全栈体系(十一)

第十章 RabbitMQ 三、SpringAMQP SpringAMQP 是基于 RabbitMQ 封装的一套模板&#xff0c;并且还利用 SpringBoot 对其实现了自动装配&#xff0c;使用起来非常方便。 SpringAmqp 的官方地址&#xff1a;https://spring.io/projects/spring-amqp SpringAMQP 提供了三个功能&…...

45基于matlab的ARIMA:AutoregressiveIntegratedMovingAverage model。

基于matlab的ARIMA&#xff1a;AutoregressiveIntegratedMovingAverage model。自回归差分移动平均模型(p,d,q)&#xff0c;AR自回归模型&#xff0c;MA移动平均模型&#xff0c;时间序列模型步骤包括&#xff1a;1. 数据平稳性检验&#xff1b;2. 确定模型参数&#xff1b;3. …...

2010年408计网

下列选项中, 不属于网络体系结构所描述的内容是&#xff08;C&#xff09;A. 网络的层次B. 每层使用的协议C. 协议的内部实现细节D. 每层必须完成的功能 本题考查网络体系结构的相关概念 再来看当今世界最大的互联网&#xff0c;也就是因特网。它所采用的TCP/IP 4层网络体系结…...

初谈Linux-Linux环境搭建(阿里云免费服务器+xshell)

文章目录 前言Linux环境搭建结尾 前言 Linux is not unix 本篇文章小编初谈Linux并搭建Linux环境&#xff08;阿里云免费服务器shell&#xff09; Linux Linux是一个开源的操作系统 环境搭建 1.点击阿里云ECS免费学生服务器 2.注册后完成学生认证 3.购买云服务器&#xf…...

如何利用AppScan扫描H5页面,进行安全测试?

前期项目组接触的都是Web安全测试&#xff0c;今天做安全测试的时候&#xff0c;有一个项目刚好有H5页面&#xff0c;用以前那种AppScan内置浏览器的探索方式是不行的&#xff0c;研究了下&#xff0c;可以使用外部设备进行探索。 AppScan有两种手动探索方式&#xff0c;一种是…...

Oracle数据库中的table@xyz是什么意思?

是DBlink访问外部表的语法。xyz是其他Oracle数据库在你所登录的用户下建立的Dblink名。通过这种方式访问其他数据库中的表。 在Oracle数据库中&#xff0c;表名后跟着符号和一个连接字符串&#xff08;xyz&#xff09;是一种用法&#xff0c;它用于指定要访问的远程数据库。 …...

springboot常见网络相关错误及原因解析

在基于spring-boot开发过程尤其是上线后&#xff0c;经常出现网络相关的错误&#xff0c;令人难以琢磨和下手&#xff0c;所以就spring-boot使用过程中可能碰到的网络相关问题进行分析&#xff0c;结合网络转包、日志报错和前端输出&#xff0c;针对网络连接超时、连接被拒绝、…...

【C语言_线程pthread_互斥锁mutex_条件触发cond 之解析与示例 (开源)】.md updata:23/11/03

文章目录 线程 pthread线程 vs 进程线程退出 等待 消息传递join:等待&#xff0c;传参void*&#xff1b; exit:退出&#xff0c;对参数赋值void**; 互斥锁 mutex互斥锁mutex条件cond_等待wait、触发signal 控制线程执行 补充: 宏-静态初始化 互斥锁/条件 线程 pthread 线程 vs…...

mongodb如何删除数据并释放空间

mongodb删除数据后不会直接释放内存空间&#xff0c;是因为使用了一种称为“延迟删除”的策略。这意味着当一个文档被删除时&#xff0c;它仍然会占用一定的内存空间&#xff0c;直到这个空间被垃圾回收器&#xff08;Garbage Collector&#xff09;回收。 删除数据操作前建议先…...

k8s之集群调度

目录 调度 工作机制 调度过程 调度算法 优先级 指定调度节点 调度 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令…...

代码随想录算法训练营第四十二天丨 动态规划part05

1049.最后一块石头的重量II 思路 本题其实就是尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;这样就化解成01背包问题了。 感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。 本题物品的重量为 stones[i]&#xff0c;物品的价…...

[css] flex 子元素自动撑开父元素宽度

对于水平排列的情况&#xff0c;我们可以设置父元素的flex-direction属性为row。这样&#xff0c;子元素将会水平排列在一行内&#xff0c;并自动撑开父元素的宽度。如果子元素的宽度总和超过了父元素的宽度&#xff0c;则子元素会被压缩&#xff0c;以适应父元素的宽度。 对于…...

全新干货!一招教你迅速提升流量主收入!包你轻松月入过万

也不怕大家笑话&#xff0c;才哥以前收入每天才一块钱&#xff0c;连瓶水都买不了&#xff0c; 可是自从我开始接触老年粉私域后&#xff0c;一个搬运公众号的流量主收益两个月后就可以用“浴火重生”来形容了。 一个搬运公众号一天的流量主收益比我原创两年的个人公众号收益还…...

连接两个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&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager 是一个 Flink 集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。每个应用都应该被唯一的 JobManager 所控制执行。 JobManger 又包含…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...