Goroutines和Channels
原文链接 https://golangbot.com/goroutines/
Goroutines
Goroutines 可以被认为是多个函数或方法同时允许。可以认为是一个轻量级的线程。与线程的花费相比是非常小的。
与线程相比的优势
- Goroutines 非常的轻量级,只需要几kb的内存分配 并且是可以根据需要动态可伸缩的。而线程的内存分配大小是固定的
- Goroutines 可以多路复用到几个OS线程中。可能只有一个线程对应到很多歌Goroutines.如果有任何一个Goroutine等待了 比如说需要用户输入 那么另外一个OS线程就会被创建 然后剩下的Goroutines 就会被移动到新的OS线程中被执行
- Goroutines使用channels沟通。channels被设计在多个Goroutines共享内存时 防止竞态的发生。channels可以被认为是Goroutines的沟通管道
开始运行一个Goroutine
例子
package main
import (
"fmt"
)
func hello() {
fmt.Println("Hello world goroutine")
}
func main() {
go hello()
//time.Sleep(1 * time.Second)
//fmt.Println("main function")
fmt.Println("main function")
}
执行这段程序之后 不会有任何输出
- 当执行一个Goroutine,goroutine会立即返回并执行下一段代码 以至于任何goroutine的返回值都会被忽略掉
- 当主Goroutine停止之后 其它任何的Goroutie也都会被终止
channels
- channels可以认为是Goroutines的沟通通道。
例子
package main
import (
"fmt"
)
func hello(done chan bool){
fmt.Println("hello goroutine")
done <- true
}
func main(){
done := make(chan bool)
go hello(done)
<-done
fmt.Println("main function")
}
- <-done 这行代码会阻止程序继续往下运行 直到Goroutine写了数据到这个channel之中 然后channel里面收到数据之后 程序会继续往下进行
- 如果需要等待多个Goroutine 则需要发送多个值到channel 也相应的要有多个相对应的接收channel
Deadlock
如果从一个Goroutine通过通道发送了数据 那么被认为会有另外一个Goroutine接收相对应的数据 如果没有的话就会产生paninc 也就发生了死锁
相似的 如果Goroutine从一个channel钟等待数据 那么应该会有另外一个Goroutine通过channle发送数据 否则的话也会发生paninc
例子
package main
func main() {
ch := make(chan int)
ch <- 5
}
- fatal error: all goroutines are asleep - deadlock!
Unidirectional channels(单向channel)
例子1
package main
import "fmt"
func sendData(sendch chan<- int) {
sendch <- 10
}
func main() {
sendch := make(chan<- int) //只运行向channel发送数据
go sendData(sendch)
fmt.Println(<-sendch) //这里从channel钟接收数据 则报错
}
例子2
//这里定义了一个只往channel发送的类型
func sendData(sendch chan<- int) {
sendch <- 10
}
func main() {
chnl := make(chan int)
go sendData(chnl)
fmt.Println(<-chnl)
}
Closing channels and for range loops on channels
- 发送者是可以关闭channel 来通知接收者没有数据要往这个channel中发送了
- 接收者可以使用另外一个变量来检测是否channel已经关闭了
v, ok := <- ch
例子
package main
import (
"fmt"
)
func producer(c chan int){
for i:=0; i < 10; i++{
c <- i
}
close(c)
}
func main() {
ch := make(chan int)
//for{
// v,ok := <-ch
// if ok == false{
// break
// }
//
// fmt.Println("Received ",v,ok)
//}
for v := range ch{
fmt.Println("Received ",v)
}
}
Goroutines和Channels的更多相关文章
- 如果这种方式导致程序明显变慢或者引起其他问题,我们要重新思考来通过 goroutines 和 channels 来解决问题
https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/09.3.md 9.3 锁和 sync 包 在一些复杂的程序中,通常通 ...
- Goroutines和Channels(五)
Channels也可以用于将多个goroutine连接在一起,一个Channel的输出作为下一个Channel的输入.这种串联的Channels就是所谓的管道(pipeline).下面的程序用两个ch ...
- Goroutines和Channels(四)
如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制. 一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值 ...
- Goroutines和Channels(三)
clock服务器每一个连接都会起一个goroutine.在本节中我们会创建一个echo服务器,这个服务在每个连接中会有多个goroutine.大多数echo服务仅仅会返回他们读取到的内容,就像下面这个 ...
- Goroutines和Channels(二)
网络编程是并发大显身手的一个领域,由于服务器是最典型的需要同时处理很多连接的程序,这些连接一般来自于彼此独立的客户端. 本小节,我们会讲解go语言的net包,这个包提供编写一个网络客户端或者服务器程序 ...
- Goroutines和Channels(一)
Go语言中的并发程序可以用两种手段来实现.本章讲解goroutine和channel,其支持“顺序通信进程”(communicating sequential processes)或被简称为CSP.C ...
- ARTS-S golang goroutines and channels(二)
向tcp服务端发消息 package main import ( "io" "log" "net" "os" ) fun ...
- ARTS-S golang goroutines and channels(一)
先用golang实现一个简单的tcp服务端,假定文件名为clock1.go // clock1.go package main import ( "fmt" "io&qu ...
- [转]50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs
http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ 50 Shades of Go: Traps, Gotc ...
随机推荐
- Token认证登录以及权限控制
IdentityServer4实现Token认证登录以及权限控制 相关知识点 不再对IdentityServer4做相关介绍,博客园上已经有人出了相关的系列文章,不了解的可以看一下: 蟋蟀大神的: ...
- C#中的XML文档注释-推荐的文档注释标记
文档注释是为了方便自己和他人更好地理解代码所实现的功能.下面记录了一些常用的文档注释标记: <C> 用法: <c>text</c> 将说明中的文本标记为代码.例如: ...
- 用TextWriterTraceListener实现建议log文件记录
log4net之类3方组件确实很方便,但是想写个小小的demo之类的程序,有点用不起啊. 微软自带的TraceListener要实现一个简易的日志帮助类还是很简单的,直接上代码,自己备用,也希望对同样 ...
- html学习笔记-XML
html学习笔记-XML Table of Contents 1. XML简介 2. XML用途 3. XML树结构 4. XML语法 5. XML元素 6. XML属性 7. XML验证 8. XM ...
- IOSruntime : 运行时机制
首先必须明白的: 1.是什么 1> runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API 2> 平时编写的OC代码, 在程序运行过程中, 其实最 ...
- MySQL开启skip-name-resolve和skip-networking优化
使用skip-name-resolve增加远程连接速度 skip-name-resolve 该选项表示禁用DNS解析,属于官方一个系统上的特殊设定不管,链接的的方式是经过hosts或是IP的模式,他都 ...
- Dictionary(支持 XML 序列化),注意C#中原生的Dictionary类是无法进行Xml序列化的
/// <summary> /// Dictionary(支持 XML 序列化) /// </summary> /// <typeparam name="TKe ...
- Outlook 客户端无法通过 MAPI over HTTP协议 连接
随着Exchange 版本更新升级,是否进行验证客户端建立MapiHttp连接所需的服务器设置已正确配置.即使服务器,负载均衡器和反向代理的所有设置都正确,您可能会遇到连接到Exchange Serv ...
- sqlserver创建触发器
Create TRIGGER [dbo].[tr_Delete_AllocationedDN] --删除指定账户已分配未拣货的任务 ON [dbo].[FRU_PickLocationNew] --触 ...
- SAP云平台的Document Service
SAP云平台以微服务的方式提供了Document的CRUD(增删改查)操作.该微服务基于标准的CMIS协议(Content Management Interoperability Service). ...