dpbf62565 2018-05-25 08:32
浏览 23

Goroutine已启动但未执行或部分执行,即使使用WaitGroup进行同步

I ran into a weird problem when using data received through channel from another goroutine to start multiple goroutines to reverse linked list simultaneously, which has troubled me for many days, I just want to split list into a couple of sublist without break link and then respectively start goroutine to reverse it, but I always get runtime error as below output shows when running code, I really don't know how to fix it after I tried many changes but still got the same error, can someone point out the problem or give me advice? any help you can give is welcome and appreciated, It would be nice if you can provide improved code, thanks in advance!

UPDATE: the problem was caused by memory corruption due to data race, it has been solved by using read-write lock!

Here is my code:

package main

import "sync"

type node struct {
    data int
    next *node
}

type LinkedList struct {
    head *node
    size int
}

type splitResult struct {
    beforeHead, head, tail *node
}

func splitList(head *node, sizoflst, sizofsublst int) <-chan *splitResult {
    nGoroutines := sizoflst / sizofsublst
    if sizoflst < sizofsublst {
        nGoroutines++
    } else {
        if (sizoflst % sizofsublst) >= 6 {
            nGoroutines++
        }
    }
    ch := make(chan *splitResult, nGoroutines)
    go func() {
        defer close(ch)
        var beforeHead *node
        tail := head
        ct := 0
        for i := 0; i < nGoroutines; i++ {
            for ct < sizofsublst-1 && tail.next != nil {
                tail = tail.next
                ct++
            }
            if i == nGoroutines-1 {
                testTail := tail
                for testTail.next != nil {
                    testTail = testTail.next
                }
                ch <- &splitResult{beforeHead, head, testTail}
                break
            }
            ch <- &splitResult{beforeHead, head, tail}
            beforeHead = tail
            head = tail.next
            tail = head
            ct = 0
        }
    }()
    return ch
}

func reverse(split *splitResult, ln **node, wg *sync.WaitGroup) {
    defer wg.Done()
    move := split.head
    prev := split.beforeHead
    if split.tail.next == nil {
        *ln = split.tail
    }
    for move != split.tail.next {
        temp := move.next
        move.next = prev
        prev = move
        move = temp
    }
}

func (ll *LinkedList) Reverse(sizofsublst int) {
    var lastNode *node
    var wg sync.WaitGroup
    if ll.head == nil || ll.head.next == nil {
        return
    }
    splitCh := splitList(ll.head, ll.size, sizofsublst)
    for split := range splitCh {
        wg.Add(1)
        go reverse(split, &lastNode, &wg)
    }
    wg.Wait()
    ll.head = lastNode
}

func (ll *LinkedList) Insert(data int) {
    newNode := new(node)
    newNode.data = data
    newNode.next = ll.head
    ll.head = newNode
    ll.size++
}

func main() {
    ll := &LinkedList{}
    sli := []int{19, 30, 7, 23, 24, 0, 12, 28, 3, 11, 18, 1, 31, 14, 21, 2, 9, 16, 4, 26, 10, 25}
    for _, v := range sli {
        ll.Insert(v)
    }
    ll.Reverse(8)
}

output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x458db5]

goroutine 21 [running]:
main.reverse(0xc4200820a0, 0xc420096000, 0xc420098000)
        /home/user/go/src/local/stackoverflow/tmp.go:69 +0x75
created by main.(*LinkedList).Reverse
        /home/user/go/src/local/stackoverflow/tmp.go:85 +0x104
  • 写回答

1条回答 默认 最新

  • donglongqiao9595 2018-05-27 11:46
    关注

    I think your problem is just assigning a value to Nil. Don't assign a Nil pointer in every place.

    Code Here

    评论

报告相同问题?

悬赏问题

  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口