Go基础编程实践(七)—— 并发
同时运行多个函数
观察常规代码和并发代码的输出顺序。
// 常规代码,顺序执行,依次输出
package main
import (
"fmt"
"time"
)
func main() {
strN := []string{"a", "b", "c", "d"}
for _, strV := range strN {
time.Sleep(time.Second)
fmt.Println(strV)
}
intN := []int{1, 2, 3, 4}
for _, intV := range intN {
time.Sleep(time.Second)
fmt.Println(intV)
}
}
// 并发代码,并发执行,无序输出
package main
import (
"fmt"
"time"
)
func main() {
go func() {
strN := []string{"a", "b", "c", "d"}
for _, strV := range strN {
time.Sleep(time.Second)
fmt.Println(strV)
}
}()
go func() {
intN := []int{1, 2, 3, 4}
for _, intV := range intN {
time.Sleep(time.Second)
fmt.Println(intV)
}
}()
// 防止main routine过早退出
time.Sleep(10 * time.Second)
}
通道的关闭
// 生产者关闭通道
package main
import (
"time"
"fmt"
)
func main() {
channel := make(chan string)
go func() {
names := []string{"Jack", "Mike", "John", "Kitty"}
for _, name := range names {
time.Sleep(time.Second)
// fmt.Println(name)
channel <- name
}
// 发送完毕关闭通道,否则引起死锁
close(channel)
}()
for data := range channel {
fmt.Println(data)
}
}
在通道中传递数据
// 利用无缓冲通道同步传递数据
package main
import "fmt"
func main(){
nameChannel := make(chan string)
done := make(chan string)
go func(){
names := []string {"tarik", "michael", "gopi", "jessica"}
for _, name := range names {
fmt.Println("Processing the first stage of: " + name)
nameChannel <- name
}
close(nameChannel)
}()
go func(){
for name := range nameChannel{
fmt.Println("Processing the second stage of: " + name)
}
done <- ""
}()
<-done
}
// 利用有缓冲通道传递数据,提高性能
package main
import "fmt"
func main(){
nameChannel := make(chan string, 5)
done := make(chan string)
go func(){
names := []string {"tarik", "michael", "gopi", "jessica"}
for _, name := range names {
fmt.Println("Processing the first stage of: " + name)
nameChannel <- name
}
close(nameChannel)
}()
go func(){
for name := range nameChannel{
fmt.Println("Processing the second stage of: " + name)
}
done <- ""
}()
<-done
}
并发等待
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
// 遍历一次,增加一次计数
wg.Add(1)
go func(){
fmt.Println("Hello World")
// 执行一次,减少一次计数
wg.Done()
}()
}
// 等待计数归零,结束程序
wg.Wait()
}
// 利用通道等待
package main
import (
"time"
"fmt"
)
func main() {
channel := make(chan string)
go func() {
names := []string{"Jack", "Mike", "John", "Kitty"}
for _, name := range names {
time.Sleep(time.Second)
fmt.Println(name)
// channel <- name
}
// 遍历完毕向通道发送数据,告诉main routine已执行完毕
channel <- ""
}()
// main routine收到数据,退出程序
// 因为只是为了同步,不需要通道中的数据,所以将数据抛弃
<-channel
}
选择并发结果
package main
import (
"time"
"fmt"
)
func main() {
channel1 := make(chan string)
channel2 := make(chan string)
go func(){
time.Sleep(1*time.Second)
channel1 <- "Hello from channel1"
}()
go func(){
time.Sleep(1 * time.Second)
channel2 <- "Hello from channel2"
}()
var result string
// select随机选择满足条件的case
select {
case result = <-channel1:
fmt.Println(result)
case result = <-channel2:
fmt.Println(result)
}
}
Go基础编程实践(七)—— 并发的更多相关文章
- Go基础编程实践(十)—— 数据库
从数据库中读取数据 在http://sqlitebrowser.org/下载sqlite3可视化工具,在本main.go同目录下创建personal.db数据库,创建表如下: package main ...
- Go基础编程实践(九)—— 网络编程
下载网页 package main import ( "io/ioutil" "net/http" "fmt" ) func main() ...
- Go基础编程实践(八)—— 系统编程
捕捉信号 // 运行此程序,控制台将打印"Waiting for signal" // 按Ctrl + C 发送信号以关闭程序,将发生中断 // 随后控制台依次打印"Si ...
- Go基础编程实践(六)—— 文件
检查文件是否存在 在此程序同目录下创建log.txt文件,以检测. package main import ( "os" "fmt" ) func main() ...
- Go基础编程实践(五)—— 错误和日志
自定义错误类型 Go中可以使用errors.New()创建错误信息,也可以通过创建自定义错误类型来满足需求.error是一个接口类型,所有实现该接口的类型都可以当作一个错误类型. // error类型 ...
- Go基础编程实践(四)—— 数组和map
数组去重 package main import "fmt" func main(){ intSlice := []int{1,5,5,5,5,7,8,6,6, 6} fmt.Pr ...
- Go基础编程实践(三)—— 日期和时间
日期和时间 package main import ( "fmt" "time" ) func main() { // 获取当前时间 current := ti ...
- Go基础编程实践(二)—— 类型转换
bool to string strconv包的FormatBool函数用于将bool转为string package main import ( "fmt" "strc ...
- Go基础编程实践(一)—— 操作字符串
修剪空格 strings包中的TrimSpace函数用于去掉字符串首尾的空格. package main import ( "fmt" "strings" ) ...
随机推荐
- LOJ3097 SNOI2019 通信 题解
题目链接 费用流,当建边需要依靠位置和权值两个偏序关系时,可以用cdq分治优化建边. 代码: #include<bits/stdc++.h> using namespace std; #d ...
- SpringCloud:学习Gateway网关拦截器的ServerWebExchange
1.Gateway的拦截器 我们要在项目中实现一个拦截器,需要继承两个类:GlobalFilter, Ordered GlobalFilter:全局过滤拦截器,在gateway中已经有部分实现,具体参 ...
- Fluent Meshing生成空心球体网格(空心部分不生成网格)
原视频下载地址: https://pan.baidu.com/s/1OJdHuIJd7pAr7cHgVCD_0g 密码: puiq
- KAFKA && zookeeper 集群安装
服务器:#vim /etc/hosts10.16.166.90 sh-xxx-xxx-xxx-online-0110.16.168.220 sh-xx-xxx-xxx-online-0210.16.1 ...
- [Gamma阶段]第九次Scrum Meeting
Scrum Meeting博客目录 [Gamma阶段]第九次Scrum Meeting 基本信息 名称 时间 地点 时长 第九次Scrum Meeting 19/06/05 大运村寝室6楼 20min ...
- 用Eclipse的maven方式创建JFinal项目
- ZooKeeper相关资料集锦
1.ZooKeeper相关概念总结 https://github.com/Snailclimb/JavaGuide/blob/master/docs/system-design/framework/Z ...
- dubbo连接过程
场景1 启动时 dubbo服务提供端在Zookeeper上注册的节点目录:假设接口名称是:com.bob.dubbo.service.CityDubboService dubbo服务提供端连接到注册中 ...
- javascript常用方法 - String
// 1.长字符串 // 1.1 let longString1 = "This is a very long string which needs " + "to wr ...
- abd shell的相关命令
http://adbshell.com/commands/adb-shell-pwd adb shell pwd adb shell rm -rf /sdcard/DCIM/