go 协程

golang中的并发是函数相互独立运行的能力。Goroutines是并发运行的函数。Golang提供了

  1. 如何实现go协程
    只需要在函数前面加上go即可
go task()
package mainimport ("fmt""time"
)func show(msg string) {for i := 0; i < 5; i++ {fmt.Printf("msg: %v\n", msg)time.Sleep(time.Microsecond * 1000)}
}func main() {go show("go show") //开辟goroutines中运行show("haha")       //这个会在main函数的goroutines中运行//注意协程是主进程的守护进程,主进程结束,协程就结束了,不管运没运行完fmt.Println("end..........")
}
  1. channel
    它是一个数据管道,可以往里面写数据,从里面读数据。
    channel 是 goroutine 之间数据通信桥梁,而且是线程安全的。
    channel 遵循先进先出原则。
    写入,读出数据都会加锁。
    channel 可以分为 3 种类型:
  • 只读 channel,单向 channel
  • 只写 channel,单向 channel
  • 可读可写 channel

channel 还可按是否带有缓冲区分为:

  • 带缓冲区的 channel,定义了缓冲区大小,可以存储多个数据
  • 不带缓冲区的 channel,只能存一个数据,并且只有当该数据被取出才能存下一个数据
unbuffered:=make(channel int)
buffered:=make(channel int,10)
package mainimport ("fmt""math/rand""time"
)var channeltest = make(chan int)func show(msg string) {value := rand.Intn(10)channeltest <- value // 往管道中写数据}func main() {defer close(channeltest) // 关闭管道go show("go show")       //开辟goroutines中运行time.Sleep(time.Second * 1)value := <-channeltest //从channel中获取数据fmt.Printf("value: %v\n", value)//注意协程是主进程的守护进程,主进程结束,协程就结束了,不管运没运行完fmt.Println("end..........")
}
  1. waitgroup实现同步
    类似于.net中的task wait,你可以取消下面wg 的试试看两者的区别,我们添加完wg后发现,a以及b函数都执行完毕
package mainimport ("fmt""sync""time"
)var wg sync.WaitGroupfunc a() {defer wg.Done()for i := 0; i < 10; i++ {fmt.Println("a函数")time.Sleep(time.Microsecond * 100)}
}func b() {defer wg.Done() //别忘了在一次执行完毕后运行这个函数for i := 0; i < 10; i++ {fmt.Println("b函数")time.Sleep(time.Microsecond * 100)}
}func main() {wg.Add(1) //在每一个go之前执行这个行数go a() //开辟goroutines中运行wg.Add(1)go b()wg.Wait()//注意协程是主进程的守护进程,主进程结束,协程就结束了,不管运没运行完fmt.Println("end..........")
}
  1. Mutex
    锁,用来解决同时访问全局变量
package mainimport ("fmt""runtime""sync""time"
)var wg sync.WaitGroup
var value int = 100
var lock sync.Mutexfunc a() {defer wg.Done()for i := 0; i < 100; i++ {lock.Lock()value += 1lock.Unlock()fmt.Println("a++")time.Sleep(time.Microsecond * 100)}
}func b() {defer wg.Done()for i := 0; i < 100; i++ {lock.Lock()value -= 1lock.Unlock()fmt.Println("a--")time.Sleep(time.Microsecond * 100)}
}func main() {fmt.Printf("runtime.NumCPU(): %v\n", runtime.NumCPU())runtime.GOMAXPROCS(8) //最大并发wg.Add(1)go a()wg.Add(1) //开辟goroutines中运行go b()wg.Wait()fmt.Println("end..........")fmt.Printf("value: %v\n", value)
}
  1. runtime包
  • runtime.Gosched() 让出CPU,重新等待安排任务
package mainimport ("fmt""runtime"
)func a() {for i := 0; i < 2; i++ {fmt.Println("a函数")}}func main() {fmt.Printf("runtime.NumCPU(): %v\n", runtime.NumCPU())runtime.GOMAXPROCS(8) //最大并发go a()                //开辟goroutines中运行for i := 0; i < 2; i++ {runtime.Gosched() //让出CPU,执行A函数fmt.Printf("i: %v\n", i)}fmt.Println("end..........")
}
  • runtime.Goexit() 退出协程
  • runtime.GOMAXPROCS(8) 最大并发
  1. select Switch
  • select是Go中的一个控制结构,类似于Switch语句,用于处理异步IO操作。select会监听语句中channel的读写操作,当case中channel读写操作为非阻塞状态时,将会触发相应的动作
  • select中的case语句必须是一个channel操作
  • select中的default自居总是可运行的
  • 如果有多个case都可以运行,select会随机公平的选出一个执行,其他不会执行
  • 如果没有可执行的case语句,且有default语句,那么会执行default
  • 如果没有可运行的case语句,且没有default语句,select将阻塞,知道某个case可以运行
package mainimport ("fmt""time"
)var valueint = make(chan int)
var valurstring = make(chan string)func main() {//关闭通道后会读取类型默认值,如int默认值为0go func() {valueint <- 100valurstring <- "haha"defer close(valueint)defer close(valurstring)}()for {select {case r := <-valueint:fmt.Printf("valueint: %v\n", r)case r := <-valurstring:fmt.Printf("valurstring: %v\n", r)default:fmt.Println("default .....")}time.Sleep(time.Second)}
}
  1. ticker
    ticker会一直运行,timer只运行一次
package mainimport ("fmt""runtime""time"
)var valueint = make(chan int)func main() {ticker := time.NewTicker(time.Second)//关闭通道后会读取类型默认值,如int默认值为0go func() {//每秒钟随机的往通道插入数据for _ = range ticker.C {select {case valueint <- 1:case valueint <- 2:case valueint <- 3:}}}()var sum intfor v := range valueint {fmt.Printf("v: %v\n", v)sum += vif sum >= 10 {runtime.Goexit()}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/60179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务学习资料

文章目录 参考资料一. 微服务概述1. CAP理论2. BASE理论3. SpringBoot 与 SpringCloud对比 二. 服务注册&#xff1a;Zookeeper,Eureka,Nacos,Consul1. Nacos两种健康检查方式&#xff1f;2. nacos中负责负载均衡底层是如何实现的3. Nacos原理4. 临时实例和持久化(非临时)实例 …

第三届计算机、物联网与控制工程国际学术会议(CITCE 2023)

第三届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2023) The 3rd International Conference on Computer, Internet of Things and Control Engineering&#xff08;CITCE 2023) 第三届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2023&#xff09;…

相同二叉树判断

目录 题目题目要求示例 解答方法一、实现思路时间复杂度和空间复杂度代码 方法二、实现思路时间复杂度和空间复杂度代码 题目 相同二叉树判断 题目要求 题目链接 示例 解答 方法一、 递归 实现思路 如果两棵树从根结点一起访问&#xff0c;当有一个结点不相等时就返回f…

自动化运维工具—Ansible

一、Ansible概述1.1 Ansible是什么1.2 Ansible的特性1.3 Ansible的特点1.4 Ansible数据流向 二、Ansible 环境安装部署三、Ansible 命令行模块&#xff08;1&#xff09;command 模块&#xff08;2&#xff09;shell 模块&#xff08;3&#xff09;cron 模块&#xff08;4&…

【Tkinter系列07/15】小部件Message、下拉菜单、移动窗

17. 小部件Message 此小部件类似于小部件 &#xff08;请参见第 12 节 “标签小部件”&#xff09;&#xff0c;但它适用于 在多行上显示消息。所有文本将 以相同的字体显示;如果需要显示文本 使用多种字体&#xff0c;请参见第 24 节 “文本小部件”。Label 创建新构件作为子…

【Android】关于binder_calls_stats服务

Android 9上有了binder_calls_stats服务&#xff0c;提供了java层的binder统计&#xff0c; Android中的Binder Call Stats&#xff08;Binder调用统计&#xff09;是一项用于监控和记录Android系统中Binder通信的统计信息的功能。Binder是Android中的一种进程间通信&#xff…

Linux安装Portainer(简洁版)

项目简介Docker安装 1.安装命令&#xff1a;curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.启动&#xff1a;systemctl start docker3.停止&#xff1a;systemctl stop docker4.重启&#xff1a;systemctl restart docker5.开机启动&#xff1a;system…

25.CSS自定义形状按钮与悬停效果

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>CSS Custom Shape Button</title><link rel="stylesheet" href="style.css"> </head> <body&…

新型安卓恶意软件使用Protobuf协议窃取用户数据

近日有研究人员发现&#xff0c;MMRat新型安卓银行恶意软件利用protobuf 数据序列化这种罕见的通信方法入侵设备窃取数据。 趋势科技最早是在2023年6月底首次发现了MMRat&#xff0c;它主要针对东南亚用户&#xff0c;在VirusTotal等反病毒扫描服务中一直未被发现。 虽然研究…

【高性能计算】opencl语法及相关概念(三)事件,内存

opencl中的事件概念 当谈到OpenCL中的事件时&#xff0c;它们代表了执行的各个阶段或操作的状态信息。通过使用事件&#xff0c;您可以跟踪和管理内核执行以及内存操作的进度和顺序。以下是与OpenCL事件相关的关键概念&#xff1a; 创建事件&#xff1a;您可以使用clCreateUse…

【MATLAB第70期】基于MATLAB的LightGbm(LGBM)梯度增强决策树多输入单输出分类预测模型(全网首发,敬请期待)

【MATLAB第70期】基于MATLAB的LightGbm(LGBM)梯度增强决策树多输入单输出分类预测模型&#xff08;全网首发&#xff0c;敬请期待&#xff09; (LGBM)是一种基于梯度增强决策树(GBDT)算法。 基于MATLAB的LightGbm即将研究测试上线。 下一个研究对象&#xff1a; ABCBOOST模型 一…

VMware虚拟机快照与克隆,保存系统运行环境

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言1. 快照的作用1.1 创建虚拟机快照1.2 管理虚拟机快照2. 克隆的作用2.1 创建克隆虚拟机前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家…

hutool工具

Hutool是一个Java工具包 参考&#xff1a;https://www.hutool.cn/ <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.6.3</version> </dependency>Convert类型转换工具类 //转换为…

股票历史数据下载 api

1 网址 Nasdaq Data Link 2 url 测试 https://www.quandl.com/api/v3/datasets/WIKI/AAPL.json?api_key注册的apikey 3 Quandl提供不同的订阅计划&#xff0c;每个订阅计划都有不同的数据访问权限和API请求次数限制。具体收费方式如下&#xff1a;免费订阅计划&#xff1…

网络常见安全漏洞

引言 随着互联网的迅猛发展&#xff0c;网络安全问题日益严重。在网络世界中&#xff0c;各种常见的安全漏洞给人们的通信和数据安全带来了巨大的威胁。本文将介绍一些常见的网络安全漏洞&#xff0c;并提供一些防范措施。 1. XSS&#xff08;跨站脚本攻击&#xff09; 跨站…

【AI】数学基础——数理统计(概念参数估计)

概率论 文章目录 3.6 数理统计概念与定理3.6.1 概率论与数理统计区别3.6.2 基本定理大数定理马尔科夫不等式切比雪夫不等式中心极限定理 3.6.3 统计推断的基本问题 3.7 参数估计3.7.1 频率派点估计法矩阵估计法极大似然估计点估计量的评估 区间估计 3.7.2 贝叶斯派贝叶斯定理条…

云安全攻防(十三)之 使用minikube安装搭建 K8s 集群

使用minikube安装搭建 K8s 集群 Kubernetes 是一个可移植的、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化,一般来说K8s安装有三种方式&#xff0c;分别是Minikube装搭建 K8s 集群&#xff0c;特点是只有一个节点的集群&…

Linux系统文件权限修改:permission denied

最近遇到文件夹权限的问题 通过命令发现www缺少写和执行的权限 然后赋予所有权限 下面是一些详解&#xff1a; 要赋予文件或目录写入权限&#xff0c;可以使用 chmod 命令。 命令的基本语法是&#xff1a; chmod <permissions> <file or directory>其中 <…

对称加密 非对称加密 AC认证 https原理

文章目录 对称加密及漏洞非对称加密及漏洞什么是数据摘要&#xff08;也称数据指纹&#xff09;什么是CA认证CA证书签发过程https通信方案 对称加密及漏洞 对称加密是一种加密算法&#xff0c;使用相同的密钥&#xff08;也称为对称密钥&#xff09;用于加密和解密数据。在对称…