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" ) ...
随机推荐
- Vuejs指令
一.内置指令 ①v-text:和 {{}} 一样,唯一的区别是,{{}} 会造成闪烁问题,而 v-text 不会有闪烁问题 <div id="app"> <h1 ...
- 16-网页,网站,微信公众号基础入门(网页版MQTT,页面控件位置调整入门)
https://www.cnblogs.com/yangfengwu/p/11200767.html 说一下,只要你java学的很好,那么几乎所有的语言都不在话下了 来看一下样式设置 运行 在左上角感 ...
- discuz插件开发
首先请修改global里的配载文件$_config['plugindeveloper'] = 2; 然后应用中心,点击设计插件 模块选择管理中心即可在应用里面显示链接 开发资料参考:http://fa ...
- webpack4.0构建项目流程
webpack4.0构建项目流程,具体的就不一一唠叨了,这里给出构建流程步骤: 流程大图: 下载高清大图
- 冰多多团队-第十次Scrum例会
冰多多团队-alpha第十次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 牛雅哲 修复了Iatdemo语音接口的bug,整个demo pipeline跑通 为词库设计更多的扩展模块和扩展 ...
- [技术博客]JSCover+selenium获得js代码覆盖率
本文档讲解了我们是如何使用JSCover来获得Selenium的测试样例的js代码文件的执行覆盖率的. 事实上网上有挺多博客讲这玩意儿了,不过完全按照网上已有的教程去弄的的话,并无法满足我们的需要. ...
- Spring Cloud Zuul 概览
什么是API网关 网关这个词其实是一个硬件概念.因为按照定义,网络网关出现在网络的边缘,所以防火墙和代理服务器等相关功能 往往与之集成在一起.在家庭网络 和小型企业中,宽带路由器通常充当网络网关.它将 ...
- 《自然语言理解(Natural Language Understanding)》(2016-03-17)阅读笔记
原文链接:https://yq.aliyun.com/articles/8301 作者:李永彬 发布时间:2016-03-17 16:37:47 自然语言理解(Natural Language Und ...
- Proj.4 升级新版本5.x和6.x
目录 Proj.4 升级新版本5.x和6.x 0.缘起 1.5.x和6.x更新情况简述 PROJ 5.x 更新 PROJ 6.x 更新 2.从PROJ.4向新版本迁移 迁移到5.x版本 迁移到6.x版 ...
- [转]跨域问题(CORS / Access-Control-Allow-Origin)
原文链接:https://blog.csdn.net/xcbeyond/article/details/84453832 1.前言 最近在项目中,调用Eureka REST接口时,出现了CORS跨越问 ...