并发添加节点到链表golang

我正在尝试使用通道和 goroutines 同时将节点添加到链表中。但是,我似乎做错了什么。这是我到目前为止所写的内容。


目前,我的打印功能只是重复第 8 个节点。这似乎适用于其他链接列表,所以我不完全理解这个问题。任何帮助都会很棒。这是我写的代码


func makeNodes(ctx context.Context, wg *sync.WaitGroup, ch chan Node) {

    defer wg.Done()

    for i := 0; i < 9; i++ {

        tmp := Node{Data: i, Next: nil}

        ch <- tmp

    }

    <-ctx.Done()

    return

}


type Node struct {

    Data int

    Next *Node

}


type List struct {

    Head   *Node

    Length int

    Last   *Node

}


func (l *List) addToEnd(n *Node) {

    if l.Head == nil {

        l.Head = n

        l.Last = n

        l.Length++

        return

    }

    tmp := l.Last

    tmp.Next = n

    l.Last = n

    l.Length++

}


func (l List) print() {

    tmp := l.Head

    for tmp != nil {

        fmt.Println(tmp)

        tmp = tmp.Next

    }

    fmt.Println("\n")

}


func main() {

    cha := make(chan Node)

    defer close(cha)


    ctx := context.Background()

    ctx, cancel := context.WithCancel(ctx)

    var wg sync.WaitGroup


    wg.Add(1)

    list := List{nil, 0, nil}

    go makeNodes(ctx, &wg, cha)


    go func() {

        for j := range cha {

            list.addToEnd(&j)

        }

    }()


    cancel()

    wg.Wait()


    list.print()

}


蝴蝶不菲
浏览 123回答 1
1回答

手掌心

该程序分配一个结构(j在for j:= range循环中)并用从通道读取的内容重复覆盖它。这导致相同的变量(j位于固定内存位置)被多次添加到列表中。考虑将通道修改为指针通道。在main()cha := make(chan *Node)然后对于makeNodes() 每次创建一个新节点(通过Node{}),一个新的节点指针被放置到通道中。func makeNodes(ctx context.Context, wg *sync.WaitGroup, ch chan *Node) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; for i := 0; i < 9; i++ {&nbsp; &nbsp; &nbsp; &nbsp; tmp := Node{Data: i, Next: nil}&nbsp; &nbsp; &nbsp; &nbsp; ch <- &tmp&nbsp; &nbsp; }&nbsp; &nbsp; <-ctx.Done()&nbsp; &nbsp; return}下面将正确地将每个唯一的 Node 指针添加到列表中。go func() {&nbsp; &nbsp; for j := range cha {&nbsp; &nbsp; &nbsp; &nbsp; list.addToEnd(j)&nbsp; &nbsp; }}()此外,您可能会发现并非所有实体都会进入列表或从频道中读取。您用于同步生产者 ( makeNodes()) 和消费 ( for j:= range) 的方法需要改进。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go