登录
首页 >  Golang >  Go问答

通道竞争条件

来源:stackoverflow

时间:2024-04-23 21:00:35 341浏览 收藏

怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《通道竞争条件》,涉及到,有需要的可以收藏一下

问题内容

这就像一个关于通道的非常基本的问题。我已经读到无缓冲通道在发送时会阻塞,那么为什么这段代码有竞争条件呢?

有时输出是

<- create;
<- insert;
end
[create; insert;]

有时是“插入;”输出中缺失,但已写入通道。

<- create;
<- insert;
end
[create; insert;]

如果 splitchan 函数在来自 slitcmd := <-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 完成后返回。

理论要掌握,实操不能落!以上关于《通道竞争条件》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>