英文:
Concurrently Add Nodes to Linked List golang
问题
我正在尝试使用通道和goroutine并发地向链表中添加节点。然而,我似乎做错了一些事情。以下是我目前编写的代码。
目前,我的打印函数只是重复打印第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()
}
希望对你有所帮助!
英文:
I'm trying to add nodes to a linked list concurrently using channels and goroutines. I seem to be doing be something wrong, however. Here's what I've written so far.
Currently, my print function is just repeating the 8th node. This seems to work on other linked lists, so I don't totally understand the issue. Any help would be great. Here is the code that I wrote
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()
}
答案1
得分: 1
这个程序通过在for j:= range
循环中分配一个单一的结构体(j
),并重复用从通道中读取的内容覆盖它。
这导致同一个变量(j
)多次添加到列表中,但它们位于固定的内存位置。
考虑将通道修改为指针类型的通道。
在main()
函数中:
cha := make(chan *Node)
然后在makeNodes()
函数中:
每次创建一个新节点(通过Node{}
),将一个新的节点指针放入通道中。
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
}
现在,以下代码将正确地将每个唯一的节点指针添加到列表中。
go func() {
for j := range cha {
list.addToEnd(j)
}
}()
此外,你可能会发现并非所有实体都能添加到列表中或从通道中读取。你需要改进生产者(makeNodes()
)和消费者(for j:= range
)之间的同步方法。
英文:
This program allocates a single structure (j
in the for j:= range
loop) and repeatedly overwrites it with the contents read from the channel.
This results in the same variable (j
, at a fixed memory location) being added to the list multiple times.
Consider modifying the channel to be a channel of pointers.
In main()
cha := make(chan *Node)
Then for makeNodes()
Each time a new node is created (via Node{}
), a new Node pointer is placed into the channel.
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
}
The following will now correctly add each unique Node pointer to the list.
go func() {
for j := range cha {
list.addToEnd(j)
}
}()
Also, you may find not all entities make it to the list or are read from the channel. Your method for synchronizing the producer (makeNodes()
) and consume (for j:= range
) needs work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论