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 ...
随机推荐
- mysql 驱动问题
转 : https://blog.csdn.net/bloodycuckoo/article/details/51175339 转 : https://blog.csdn.net/u010746431 ...
- replcation set (复制集)配置过程 --mongodb
一,配置规划 复制集原理(基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB) Paxos(mysql MGR 用的是变种))如果发生主库宕机,复制集内部会进行投票选举,选择一 ...
- ruby 正则表达式 匹配所有符合规则的信息
假设一个字符串当中有很多符合规则的信息,下面的例子可以把所有匹配到的结果打印出来: message="afhadhffkdf414j9tr3j43i3433094jwoert223jwew1 ...
- 【踩坑】springMVC 接收String参数没有判断为空
今天在调试iReview项目的接口时,发现新增词条和新增库的时候,某些字段即使留空POST到后台时也能当做不为空. 经过排查,发现后台是使用 String 变量名 == null 这样的语句去判断变量 ...
- 【转】pom.xml讲解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- ABAP跳转屏幕
1.call transaction语句跳转屏幕 '. CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN. . 2.调用函数 CALL FUNCTION 'M ...
- Android 开发干货,键盘状态
地址:http://www.imooc.com/article/4711 [A]stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置 [B]stateU ...
- ios 设置cell的间距
1.设置假的间距,我们在tableviewcell的contentView上添加一个view,比如让其距离上下左右的距离都是10:这个方法是最容易想到的: 2.用UIContentView来代替tab ...
- Android(java)学习笔记126:判断SD卡状态和SD卡容量
1. 判断SD卡状态和SD卡存储空间大小 当我们在使用SD卡时候,如果我们想往SD卡里读写数据,我们必须在这之前进行一个逻辑判断,那就是判断SD卡状态和SD存储空间大小: 核心代码: String s ...
- iOS 微信和支付宝关于回调处理
在支付这一块,发现讲支付集成的比较多,但是关于支付后回调处理的不多见,(当时因为这个问题懵逼了好久)就自己总结一下, 1.支付宝回调 支付宝的回调想对来说比较简单一些,因为支付宝的回调就在调起支付宝的 ...