当前位置: > > > > 通道竞争条件
通道竞争条件
来源:stackoverflow
2024-04-23 21:00:35
0浏览
收藏
怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面米云就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《通道竞争条件》,涉及到,有需要的可以收藏一下
问题内容
这就像一个关于通道的非常基本的问题。我已经读到无缓冲通道在发送时会阻塞,那么为什么这段代码有竞争条件呢?
有时输出是
<- create; <- insert; end [create; insert;]
有时是“插入;”输出中缺失,但已写入通道。
<- create; <- insert; end [create; insert;]
如果 splitchan 函数在来自 slit 的 cmd := <-c 上阻塞,它如何返回?
package main
import "fmt"
func main() {
batch := `create;insert;`
res := split(batch)
fmt.print(res)
}
func splitchan(batch string, outc chan<- string) {
b := 0
for i, c := range batch {
switch c {
case ';':
cmd := batch[b : i+1]
fmt.println("<- " + cmd)
b = i + 1
outc <- cmd
}
}
fmt.println("end")
}
func split(batch string) []string {
var res []string
c := make(chan string)
go func() {
for {
cmd := <-c
res = append(res, cmd)
}
}()
splitchan(batch, c)
close(c)
return res
}
游乐场链接:https://go.dev/play/p/wmo5otmgetl
我希望每次运行都有相同的输出:
<- create; <- insert; end [create; insert;]
我在这里缺少什么? 谢谢
正确答案
当 splitchan 写入通道时,在 goroutine 上发生的附加操作和 return res 语句是并发的。 return res 可能会看到包含一个元素或两个元素的切片。
你必须确保在返回之前,追加操作已完成:
wg:=sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
for cmd := range c {
res = append(res, cmd)
}
}()
SplitChan(batch, c)
close(c)
wg.Wait()
return res
waitgroup 确保函数在 goroutine 完成后返回。
理论要掌握,实操不能落!以上关于《通道竞争条件》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注米云公众号吧!
