Golang学习之路6-goroutine并发

news2025/8/12 5:37:05

文章目录

  • 前言
  • 一、goroutine用法
  • 二、goroutine循环
  • 三、goroutine提前退出
  • 四、goroutine双向管道
  • 五、goroutine单向管道
  • 六、监听管道
    • 如下图,可以看到当我们监听到有写入数据时会得到对应的类型数据,当没有写入时 default 一直在负责监听! ![在这里插入图片描述](https://img-blog.csdnimg.cn/af57c7a2ac544710aaac95d549eda615.png)
  • 总结


前言

什么是 goroutine?简称可以使:go程、并发

  • goroutine是与其他函数或方法同时运行的函数或方法。
  • goroutine可以被认为是轻量级线程,天生支持多并发。
  • 与线程相比,创建goroutine的成本很小,因此Go 应用程序通常会同时运行数千个goroutine。

一、goroutine用法

go语言天生支持多并发,使用方式:

  • 方式一:go func()
  • 方式二(匿名):go func(){}()
package main
import (
	"fmt"
	"time"
)
func display(count int) {
	for {
		fmt.Println("这是子go程======>:", count)
		time.Sleep(1)
		count++
	}
}

func main() {
	go display(1)

	// 匿名 子go程 函数
	//go func () {
	//	count := 1
	//	for {
	//		fmt.Println("这是子go程======>:", count)
	//		time.Sleep(1)
	//		count++
	//	}
	//}()
	
	// 主go程
	count := 1
	for {
		fmt.Println("这是主go程:", count)
		count++
		time.Sleep(1)
		if count > 2 {
			break
		}
	}
}

可以看到,主进程没有打印第3次,而子进程打印了第3次
在这里插入图片描述

二、goroutine循环

比如起3个进程跑goroutine,cpu资源会被竞争不确定谁先谁后:

for i := 0; i <= 3; i++ {
	go func() {}()
}

三、goroutine提前退出

三种退出go程方式:

  • return:只退出当前子go程函数
  • runtime.Goexit():只退出当前go程
  • os.Exit(-1):退出所以的主子go程
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	go func() {
		func() {
			fmt.Println("这是子go程 内部函数111")
			//return 			  // 只结束此函数,会执行到:子go程222
			//runtime.Goexit()    // 退出当前go程,不会执行到:子go程222
			os.Exit(-1)	          // 退出所以主子进程
		}()
		fmt.Println("子go程222")
	}()
	time.Sleep(1)
	fmt.Println("结束主go程!")
}

四、goroutine双向管道

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

ch <- value    // 把 value  发送到通道 ch
value := <-ch  // 从 ch 接收数据,并把值赋给 value 

chan双向管道:

  • 使用通讯时不需要上锁解锁;
  • 未创建容量时是无缓冲的,反之是有缓冲的;
  • 当缓冲区写满时或读取完成时会阻塞,当被读取后再恢复写入;
  • 管道的读与写次数必须对等,否则会被堵塞,①如果阻塞主go程那么程序被锁死至崩溃,②如果阻塞在子go程会出现内存泄漏;
  • 需要使用make分配空间,否则管道默认是nil,读写都会堵塞(和map一样所以建议都是make);
  • 使用goroutine管道时推荐使用for range,当管道写入完成后应关闭close(chan)
package main
import (
	"fmt"
	"time"
)

func main() {
	// 创建一个容量为10的int有缓冲管道
	numChan := make(chan int, 10)

	// 写“管道”数据
	go func() {
		for i := 1; i < 21; i++ {
			numChan <- i
			fmt.Println("11-->子go程写入数据:", i)
		}
		// 写入结束,关闭管道
		close(numChan)
	}()

	// 读“管道”数据
	go func() {
		for num := range numChan {
			fmt.Println("22-->子go程读取数据data:", num)
		}
	}()

	time.Sleep(1 * time.Second)

	// 判断管道是否关闭
	for {
		v, ok := <-numChan
		if !ok {
			fmt.Println("管道已经关闭,准备退出!!")
			break
		}
		fmt.Println("v:", v)
	}
}

五、goroutine单向管道

一般用于函数参数,比如只读、只写单向管道,看看下面和双向管道有何区别?
生产者:chan<-
消费者:<-chan
双向管道时都是:<-numChan

package main
import (
	"fmt"
	"time"
)

// 生产者:只写入数据
func producer(out chan<- int) {
	for i := 1; i < 11; i++ {
		out <- i
		fmt.Println("写入数据:", i)
	}
	close(out)
}

// 消费者:只读数据
func consumer(in <-chan int) {
	for v := range in {
		fmt.Println("读取数据:", v)
	}
}

func main() {
	// 创建一个双向通道
	numChan := make(chan int, 5)

	// 创建生产者
	go producer(numChan)

	// 创建消费者
	go consumer(numChan)

	time.Sleep(200)
}

在这里插入图片描述

六、监听管道

在多go程并发时,我们可以通过select进行监听到对应数据,突然觉得类似消息事件一样,一个负责推、一个负责监听…
select:监听多管道 (写入/读写数据、关闭管道)

package main
import (
	"fmt"
	"time"
)

func main() {
	// 创建两个管道,用来测试监听
	chan1 := make(chan int)
	chan2 := make(chan int)
	// 监听go程
	go func() {
		for {
			select {
			case data1 := <-chan1:
				fmt.Println("监听到chan111:", data1)
			case data2 := <-chan2:
				fmt.Println("监听到chan222:", data2)
			default:
				fmt.Println("正常监听中...")
				time.Sleep(2 * time.Second)
			}
		}
	}()

	// go程:两个管道分别写入数据
	go func() {
		for i := 0; i < 5; i++ {
			chan1 <- i
			i++
			chan2 <- i
		}
	}()

	count := 1
	for {
		time.Sleep(10 * time.Second)
		if count == 6 {
			break
		}
		count++
	}
}

如下图,可以看到当我们监听到有写入数据时会得到对应的类型数据,当没有写入时 default 一直在负责监听!
在这里插入图片描述

总结

以上就是今天学习的内容,本文仅仅简单介绍了goroutine的使用,而在项目中如何实践还请大家多多查阅资料了解!

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

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

相关文章

前端播放m3u8格式视频

m3u8是苹果公司推出的视频播放标准&#xff0c;是m3u的一种&#xff0c;只是编码格式采用的是UTF-8。m3u8准确来说是一种索引文件&#xff0c;使用m3u8文件实际上是通过它来解析对应的放在服务器上的视频网络地址&#xff0c;从而实现在线播放。 m3u8格式的视频是将文件分成一小…

[附源码]计算机毕业设计JAVA个性化新闻推荐系统

[附源码]计算机毕业设计JAVA个性化新闻推荐系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myba…

高级篇之ENC1V2新用法USB/RS232串口转Visca-Over-IP

高级篇之ENC1V2新用法USB/RS232串口转Visca-Over-IP术语背景现实需求大家好&#xff0c;最近ENC1-V2卖的很火&#xff0c;主要是因为发现了它的一个新用法&#xff0c;究竟是什么&#xff0c;马上揭晓。 术语 摄像机控制代码协议包括PTZ,VISCA,VISCA-OVER-IP,PELCO等, VISCA是…

java计算机毕业设计ssm求职与招聘网站的设计与实现

项目介绍 本前途招聘求职网站是针对目前仓库的实际需求,从实际工作出发,对过去的前途招聘求职网站存在的问题进行分析,完善用户的使用体会。采用计算机系统来管理信息,取代人工管理模式,查询便利,信息准确率高,节省了开支,提高了工作的效率。 本系统结合计算机系统的结构、概念…

配置hadoop模板虚拟机

文章目录前言一、VMvare安装与添加Linux虚拟机二、linux服务器更改网络配置三、安装epel-release以及关闭防火墙关闭防火墙四、配置用户权限五、卸载自带的JDK前言 本文主要讲述配置hadoop集群的前置工作之一&#xff0c;配置模板虚拟机。 模板虚拟机的用处在于&#xff0c;我…

通过工具和字节码带你深入理解运行时数据区

上篇文章介绍了JVM运行时数据区的一些信息&#xff0c;这篇文章将通过工具和字节码加深对常用的堆和虚拟机栈部分的理解。 虚拟机栈再理解 下面通过3个简单的例子再深入了解一下虚拟机栈区域。 1. 虚拟机栈的出入栈过程 public class JVMStack {public static void main(St…

【JVM学习】Jconsole 配置jmx 监控JVM

1. 配置jvm启动参数 在使用jconsole监控jvm之前&#xff0c;首先需要先打开jmx。启动jvm时&#xff0c;添加以下参数。jmx通过58088端口对外开放。 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port58088 -Dcom.sun.management.jmxremote.sslfalse -Dcom…

低代码能为企业带来什么好处

低代码自问世以来&#xff0c;逐步进入到公众视野&#xff0c;由于其可视化的操作界面、可以快速开发应用等优势&#xff0c;让企业在数字化转型过程中得到技术和速度的支撑。在低代码平台&#xff0c;技术人员和业务专业人员可通过图形界面&#xff08;而不是传统的计算机编程…

m基于matlab的OQPSK载波同步通信系统仿真,载波同步采用costas环

目录 1.算法概述 2.仿真效果预览 3.核心MATLAB代码预览 4.完整MATLAB程序 1.算法概述 OQPSK调制技术是一种恒包络调制技术&#xff0c;受系统非线性影响小&#xff0c;具有较高的带宽利用率和功率利用率&#xff0c;在卫星环境、无线环境下得到广泛应用。因此&#xff0c;在…

案例分析 丨湖仓一体助力保险企业数据战略转型升级

当下&#xff0c;海量数据结合前沿技术架构正在为保险业带来根本性的变革。本文以某知名保险机构为例&#xff0c;结合偶数行业实践经验&#xff0c;介绍保险企业如何利用湖仓一体技术推动数据战略转型升级。 背景介绍 在对该客户需求进行深度挖掘并横向比较行业现状后&#xf…

基于PHP+MySQL的图书分享平台

读书是提高一个人思维,最直接,最简单和最方便的方式。同时读书可以让自己的思想得到提升,保证自己一直都在时代的检前沿。图书是知识的载体,但是它也有它的特殊性。那就是他可以进行分享。很多时候,人们在购买图书并进行阅读之后,很可能就不再需要了,这个时候就可以和其他人进行…

SpringBoot完成查询和增加功能(简易版)

目录 一、环境准备 1、db 2、html 打开前端开发工具HBuilder X&#xff0c;把准备好的前端spboot移进去&#xff1a; 接着查看电脑的mvn版本&#xff0c;选中项目右键&#xff1a; npm -version npm i​ 3、java 在弹出的窗口中选择你需要导入的项目&#xff0c;点击ok…

python的网络请求库urllib、urllib2、urllib3、request的联系

文章目录1. 简介2. urllib3. urllib24. urllib35. requests6. 相关文章1. 简介 urllib、urllib2、urllib3、request均能通过网络访问互联网上的资源文件&#xff0c;它们通过使用统一资源定位符&#xff08;URL&#xff09;并结合re模块完成很多意想不到的操作。 urllib&…

数据库与缓存的一致性

数据库与缓存的一致性 一致性就是数据保持一致&#xff0c;在分布式系统中&#xff0c;可以理解为多个节点中数据的值是一致的。 强一致性&#xff1a;这种一致性级别是最符合用户直觉的&#xff0c;它要求系统写入什么&#xff0c;读出来的也会是什么&#xff0c;用户体验好…

Windows系统怎么加密文件夹?

Windows系统是目前使用人数最多的电脑系统&#xff0c;那么你知道在Windows系统上怎么加密文件夹吗&#xff1f;下面这篇文章&#xff0c;将向大家介绍两种Windows系统文件夹加密的方法&#xff0c;希望对你有所帮助。 方法一&#xff1a;使用超级加密3000进行加密 1、打开超级…

C和C++导出DLL后在Csharp中调用函数名的差异

参考链接&#xff1a;cc​​​​​​​在Unity中调用C代码&#xff1a;出现EntryPointNotFoundException的解决办法&#xff1a; - 知乎 (zhihu.com) __declspec(dllexport)的位置问题 - 岚之山 - 博客园 (cnblogs.com) 如果是报如下异常 System.EntryPointNotFoundExceptio…

【GlobalMapper精品教程】017:KML generator快速将坐标转为KML文件

本文介绍KML generator软件,并快速将坐标转为KML文件的使用方法,并用globalmapper中打开kml文件加以验证。本专栏配套完整的案例数据包,请打开data017.rar获取软件及数据。 文章目录 1. KML文件介绍2. kml generator软件介绍2.1 单点KML制作2.2 Excel数据KML制作2.3 文本文件…

【模电实验】【超值1 + 1】【验证性实验——分立元件“OTL“功率放大器实验】【验证性实验——分立元件稳压电源实验】

实验9-1 验证性实验——分立元件"OTL"功率放大器实验 Multisim仿真 编辑分立元件OTL功率放大器的仿真电路如下&#xff1a; 静态工作点的调试与仿真如下&#xff1a; 发射极基极集电极T1277mV998mV5.66VT26.38V6.93V12VT36.20V5.66V0V 交越失真分析如下&#xff1a…

【Linux】OS和进程概念

文章目录1.冯诺依曼体系结构2. 操作系统&#xff08;Operator System &#xff09;概念总结3. 进程描述进程-PCBtask_struct-PCB的一种task_ struct内容分类见见进程1.冯诺依曼体系结构 冯诺依曼结构也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起…

微机原理实验:字符转换为ASCII码

随记&#xff01; 要求&#xff1a; 1. 将指定数据区的字符串数据以ASCII码形式显示在屏幕上&#xff0c;并通过DOS功能调用完成必要提示信息的显示。 2. 在屏幕上显示自己的学号姓名信息。 3. 循环从键盘读入字符并回显在屏幕上&#xff0c;然后显示出对应字符的AS…