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 ...
随机推荐
- hdu6062RXD and logic gates多校题 构造
听说标算的点数是2^(n+1)级别的,也不知道我是不是比标算优一点? (话说这种题一眼看过去怎么跟题答一样) 然而并不是题答,没法手玩,来考虑一下一般解法: 考虑一个规模较小的问题:最后一位一定是0 ...
- ruby 从命令行读取文本
最常见的方式就是使用内置的get 方法,这个方法可以从命令行读取用户的输入,并在默认的情况下把读入的文本赋值给预定义变量$_. 但是get方法会保留用户在输入字符串末尾所加的换行符,当用户在输入的字符 ...
- 利用Jmeter 实现Json格式接口测试
使用Jmeter模拟http请求测试接口,请求类型为json,步骤如下: 1.启动Jmeter:找到Jmeter.bat文件双击启动Jmeter. 2.在测试计划下面添加线程组:测试计划右键--添加 ...
- 【踩坑】spring每次请求后session不一样导致无法在服务器保存信息
根据网上的资料,若想在服务器用session保存一些信息,方法如下: public Xclass Xmethod(HttpServletRequest request, HttpSession ses ...
- hard link && symbolic link
hard link :硬连接,多了一个inode,指向原始的inode,通过这个硬连接删除文件,文件不会被真正删除,而是删除这个inode symolic link:符号连接相当于快捷方式
- Dubbo封装rest服务返回结果
由于Dubbo服务考虑到一个是给其他系统通过RPC调用,另外一个是提供HTTP协议本身系统的后台管理页面,因此Dubbo返回参数在rest返回的时候配置拦截器进行处理. 在拦截器中,对返回参数封装成如 ...
- 编译错误you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
解决方法: export FORCE_UNSAFE_CONFIGURE=1
- 安装ubuntu出现BUG soft lockup的解决方法(16.04 14.04)
对于16.04而言,当时用的是UtrISO 安装的,导致安装过程用会出现 “not a com32r image” 的错误,解决方法见上文的: boot: live 华硕Z9主板安装16.04以上系统 ...
- 电话号码 马赛克*号 string类扩展
/// <summary> /// 字符串马赛克 /// </summary> /// <param name="source"></pa ...
- NullPointerException检测
APET-NPE插件工作原理 android应用程序编译的过程如下: 从图中,我们可以看出,app编译大致经历了四大阶段:java source files -> .class files -& ...