前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >循环中使用goroutine引用临时变量

循环中使用goroutine引用临时变量

原创
作者头像
用户7365393
修改2021-10-08 14:12:39
修改2021-10-08 14:12:39
78700
代码可运行
举报
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
复制
代码如下:
func main() {	var wg sync.WaitGroup	wg.Add(5)	for i := 0; i < 5; i++ {		go func() {			fmt.Println(i) 			wg.Done()		}()	}    wg.Wait()}
  1. 输出:常见的答案就是会输出 5 个 5,因为在 for 循环的 i++ 会执行的快一些,所以在最后打印的结果都是 5 这个答案不能说不对,因为真的执行的话大概率也是这个结果,但是不全。因为这里本质上是有数据竞争,在新启动的 goroutine 当中读取 i 的值,在 main 中写入,导致出现了 data race,这个结果应该是不可预知的,因为我们不能假定 goroutine 中 print 就一定比外面的 i++ 慢,习惯性的做这种假设在并发编程中是很有可能会出问题的
代码语言:javascript
代码运行次数:0
复制
正确示例:将 i 作为参数传入即可,这样每个 goroutine 拿到的都是拷贝后的数据
func main() {	var wg sync.WaitGroup	wg.Add(5)	for i := 0; i < 5; i++ {		go func(i int) {			fmt.Println(i)			wg.Done()		}(i)	}	wg.Wait()}

2.3 引起变量共享

package main

import "os"

func main() {

ParallelWrite([]byte("xxx"))

}

// ParallelWrite writes data to file1 and file2, returns the errors.

func ParallelWrite(data []byte) chan error {

res := make(chan error, 2)

// 创建/写入第一个文件

f1, err := os.Create("/tmp/file1")

if err != nil {

res <- er

} else {

go func() {

// 下面的这个函数在执行时,是使用err进行判断,但是err的变量是个共享的变量

_, err = f1.Write(data)

res <- er

f1.Close()

}()

}

// 创建写入第二个文件n

f2, err := os.Create("/tmp/file2")

if err != nil {

res <- er

} else {

go func() {

_, err = f2.Write(data)

res <- er

f2.Close()

}()

}

return res

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.3 引起变量共享
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档