go语言并发编程上
傍晚抽空学习了下go语言的并发编程,从goroutine到channel机制,从开始的稀里糊涂到现在拨开云雾见太阳的感觉,学习的过程总是令人亢奋的!当然目前的理解还是不够透彻的。下篇将举例来分析下。
goroutine
类似开辟进程、线程做法,go语言所采用的为 goroutine 。用法极其简单,也就是使用go关键字,使用方法有两种:
-
定义一个函数functionName,要异步调用时使用语句go functionName即可。
-
使用匿名函数,用法为go func(参数列表){函数执行体}(),说明最后一个()作用就是让该函数执行。
下面简单代码加深下:
/////////第一种示例代码://///////// func sayHello(name string){ fmt.Println("hello"+name) } //主程序入口 func main(){ go sayHello("PMST") } /////////第二种示例代码:////////// //主程序入口 func main(){ go func(){ fmt.Println("hello world") }() //别忘记这里的() }
现在来讲下go关键字作用,一旦将go放在函数之前,意味分配一个子routine让这个函数自个玩去(有点自身自灭的感觉),而主 routine则继续该干嘛干嘛。打个比方,手头有一堆数据,需要经过超级复杂,超级耗时的计算才能得出答案。显然我们的主routine不可能只干这一 件事,它还有其他事情需要处理。因此,我们开辟一个routine让其自个算去。
那么问题来了,这么做确实解决了主routine不被锁死的问题,又能够完成了耗时计算,可是计算出答案之后,如何回传给主routine使用呢?
这也就是下面channel的使用了
channel
goroutine 之间如何进行数据的通信?如下两种:
-
共用内存内存空间。
-
Go语言推荐的通信机制channel。
接下来是我对channel的一些理解:
-
Goroutine使用channel 接收或者发送值,而这些值只能是特定的类型,由自己指定,比如两个routine之间相互传值为int类型,那么channel类型就是chan int
-
通过make来创建channel,例如无缓存ci := make(chan int),指定缓存cib := make(chan int,2)。很明显可以看出,区别在于后面的表述,后者表示给这个通道分类了2个缓存空间,至于区别,下文马上给出。
-
channel 通过<- 来接收和发送数据。例如 channel <- value ,显然就是把值 value 发送到通道 channel 中; value := <- ch ,注意箭头,表示从通道 channel 读取数据给 value ,或者可以说从通道channel接收数据赋值给value。顺便提及其他的写法<- channel,显然也是从通道读取数据,但是没有赋值给任何一个变量,因此表示丢弃!
关于channel的阻塞问题,我想有必要着重梳理下。请看下面的总结
首先通道的接收和发送都是阻塞的,除非与之对应的一端已经准备好。通过举例来说明是最好不过了。
-
新建一个通道,channel_c := make(chan int),注意是没有分配缓存的。
-
随后往通道写入数据,channel_c <- value,由于没有分配缓存,因此这里会被堵塞掉,换句话说就是卡死在这里,只能等待,等待程序某个地方从该通道读取数据!(ps:就好比非常短的管 子,就往里塞了一个数据,就要漏出来,因此我一直手”扶着”数据,腾不出手干下面的事了。只有当接收方来拿数据了才能腾出手来干别的事。)
-
2015.04.22 -> 对上面比喻修改。ps:上面比喻的不是很恰当,我想是不是可以这么认为,channel是连通两个routine的通道,当发送者向channel里发送 数据,却迟迟等不到接收者,但秉着尽职尽责的思想,始终等待在那个位置,即channel_c := make(chan int)这条发送语句处,直到接收者接收了通道数据,才可以进行下一条语句。那么假如有缓存就不同了,就好比一个驿站,拿着数据到通道这发送“邮件”,尽 管可能没有接收者,但是我却可以先暂时放到“驿站”(缓存)这里,然后继续干自己的活,等下次再向通道发送数据时发现缓存满了,就只能耐心等待,除非这时 有人来取数据,腾出缓存空间了,才可以写入数据。
-
现在换成从通道读取数据,v := <- channel_c,分两种情况:当channel_c通道中有数据时,那肯定不会堵塞,很顺利的读过来;当channel_c通道没有数据时,那么自然又堵死了,除非程序其它地方往通道写入数据了!
-
最后讲讲关于分配了缓存的通道,例如:channel := make(chan int,2)。假如这时候往通道写入数据channel <- 2,由于分配了缓存,意味着是我可以直接写入,不会堵塞了,但这仅当我的缓存区未满的情况下才不会堵塞。下面往通道写入一个channel <- 3,这是没有问题的。不过缓存已经填满了!假如这时候你再写的话就会堵塞,只有程序某个地方从改通道读取数据腾出地方了,你才可以写入!
相关推荐
【GD32150R_EVAL_GD32F1x0_Firmware_Library_Routine】是GD32微控制器系列中的一个软件开发资源,专为GD32150R评估板设计。这个库包含了丰富的例程,帮助开发者更好地理解和使用GD32F1x0系列芯片的功能。GD32是GD ...
通过对这个示例的学习,开发者可以了解如何配置FM17550LPDC进行低功耗运行,以及如何处理低功耗模式下的中断事件。通过分析和调试这个程序,我们可以深入理解FM175xx系列芯片的低功耗机制,从而在实际项目中更好地...
总的来说,"c_menu_routine"这个项目旨在帮助C语言程序员学习如何在命令行界面中创建和管理用户菜单,以提高程序的交互性和易用性。通过研究提供的示例和代码,你可以掌握创建C语言菜单的基本步骤,并将其应用到自己...
EasyFPGA060_Routine_RAMEasyFPGA060_Routine_RAMEasyFPGA060_Routine_RAM
GD32F4_ADC0_ADC1_Routine_Parallel_modeGD32F4_ADC0_ADC1_Routine_Parallel_modeGD32F4_ADC0_ADC1_Routine_Parallel_modeGD32F4_ADC0_ADC1_Routine_Parallel_modeGD32F4_ADC0_ADC1_Routine_Parallel_modeGD32F4_ADC...
使用 ASP.NET Core 杨旭 RESTful API ReSharper ApiController P18_写代码_过滤和搜索_Routine.Api2020_2_7.rar P18 写代码:过滤和搜索
P15_处理服务器故障_P16_HTTP_HEAD_Routine.Api2020_2_7.rar P15 处理服务器故障 P16 HTTP HEAD Binding source Attributes ● [FromBody],请求的Body,默认 ● [FromForm],请求的Body中的form数据 ● [From...
使用 ASP.NET Core 3.x 构建 RESTful Web API(2020-2-7更新) P25_HTTP_OPTIONS和XML支持_Routine.Api2020_2_12.rar P25 HTTP OPTIONS和XML支持 Status:405 Method Not Allowed
本文将深入探讨FM175xx系列芯片在LPCD Routine中的工作原理和具体实现,并重点解析FM17550LPDC的功能特性。 1. **LPCD Routine简介** LPCD Routine是FM175xx系列芯片中的一个核心特性,它允许设备在无活动或低活动...
标题中的“FM175xx_Demo_LPCD_Routine_LPCD_FM17550LPDC功能”指的是一个关于FM175系列芯片的演示程序,它着重展示了低功耗模式(LPCD)的功能。FM175芯片是由飞兆半导体(Fairchild Semiconductor)或其后续公司...
总之,"GD32305R_START_GD32F30x_Firmware_Library_Routine.zip"这个压缩包为开发者提供了全面的GD32F30x系列微控制器开发资源,涵盖了硬件接口、软件编程、调试工具等多个方面,是深入学习和实践GD32F30x微控制器...
【Cortex-M0 程序开发:C++与Builder工具链详解】 在嵌入式系统开发领域,Cortex-M0 是一款广泛应用的微控制器架构,以其低功耗、高性能的特点受到众多硬件开发者青睐...不断实践和学习,你将在嵌入式世界中游刃有余。
在实践中,提供的"FM175xx_Demo_LPCD_Routine"示例代码可以作为参考,它包含了详细的注释,指导开发者如何设置和管理LPCD模式。通过分析和理解这段代码,我们可以更好地掌握FM17550LPDC的LPCD模式实现方法,从而在...
源代码通常采用C语言编写,遵循清晰的结构和注释,便于理解和学习。 在开发过程中,调试是必不可少的环节。资料可能也包含了调试工具的使用说明,如JTAG或SWD接口的连接方法,以及如何使用IDE(集成开发环境)进行...
P22_创建子资源POST_Routine.Api2020_2_8.rar 使用 ASP.NET Core 杨旭 RESTful API ReSharper ApiController P22 创建子资源POST 杨旭老师 ... ...Get请求信添加的数据的API地址 ...
在本文中,我们将深入探讨如何使用EasyFPGA平台实现加法器功能,特别是在"EasyFPGA060_Routine_Adder"项目中的应用。EasyFPGA是一款非常适合初学者和专业人士进行数字逻辑设计的开发工具,它提供了易于使用的硬件...
P19查询参数_Routine.Api2020_2_7.rar P19 查询参数 19.过滤和搜索(Coding) 当查询参数很多时,比如根据姓别,关键字等, 这时可以使用一个类,把参数放到类里面即可 在项目中新建DtoParameters文件夹 在...
HMC5883L标定补偿SW_Routine_Calibration[收集].pdf
使用 ASP.NET Core 3.x 构建 RESTful Web API(2020-2-7...P26_输入验证和DataAnnotations_Routine.Api2020_2_12.rar P26 输入验证和Data Annotations 验证三部曲 定义验证规则 按验证规则进行检查 报告验证的错误