Go基础编程实践(七)—— 并发
2024-09-03 18:46:15
同时运行多个函数
观察常规代码和并发代码的输出顺序。
// 常规代码,顺序执行,依次输出
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)
}
}
最新文章
- angular2 service component
- [No00005F]读书与心智
- Qt学习笔记 信号和槽
- oracle中一些用法总结
- java检测文件内是否包含指定内容
- C# 静态方法和非静态方法
- MSP430之频率测量,误差1Hz
- Python中的lambda函数
- Windows Phone 8 实现列表触底加载
- Code Understanding Step by Step - We Need a Task
- 设计模式(十):Decorator装饰者模式 -- 结构型模式
- Java学习笔记--AWT事件处理
- Bootstrap网站模板
- [ An Ac a Day ^_^ ] HDU 1257 基础dp 最长上升子序列
- intellij idea svn使用一 导入、更新、提交、解决冲突
- JAVAEE——BOS物流项目06:分页查询、分区导出Excel文件、定区添加、分页问题总结
- Android服务器——TomCat服务器的搭建
- eclipse工具按键翻译
- Docker 搭建 Tomcat + Mysql
- android应用程序中获取view的位置
热门文章
- A1102 | 反转二叉树
- 理解 IO_WAIT 并且了解利用包括 top htop iotop iostat 工具来查看 IO 性能
- BigDecimal代码示例
- Sql Server 2008 R2安装教程
- JavaScript初探系列(十)——Event
- 深度学习剖根问底: Adam优化算法的由来
- uniapp - 富文本编辑器editor(仅支持App和微信小程序)
- python skimage图像处理(一)
- odoo开发笔记 -- 还原数据库后,异常:ir_attachment: IOError: [Errno 2] No such file or directory: u&#39;/var/...&#39;
- 【转】模糊测试(fuzzing)是什么