从提供SIGSEGV的频道中读取:细分违规

I was trying to insert documents in the mongoDB using go-client (mgo). I create a new mongo session, and two channels for communcaition b/w go-routines, channel is used to sync b/w readFile and main, while other is to pass data read from file in readFile to db write routine insertTxn.

type Txn struct {
    Date time.Time
    Amt  float64
}



func main() {
    session, err := mgo.Dial("localhost")
    if err != nil {
        panic(err)
    }
    defer session.Close()

    channel := make(chan bool)
    txnChannel := make(chan Txn, 1e4)

    go readFile(txnChannel, channel)
    go insertTxn(session, txnChannel)

    <-channel
    time.Sleep(time.Second * 10) // waiting for insertTxn to finish

    defer func() {
        if r := recover(); r != nil {
            fmt.Println(r)
        }
    }()
}

Then, goroutine readFile is started which starts reading from an input file, and writing the data to txnChannel channel. After completion, it marks the completion by writing to channel channel.

func readFile(txnChannel chan<- Txn, channel chan<- bool) { // write only channel
        txnFile, err := os.Open("path/to/dir/txns.txt")
        if err != nil {
            panic(err)
        }
        txnReader := bufio.NewReader(txnFile)
        defer func() {
            txnFile.Close()
            channel <- true
        }()
        var data []string
        var txn Txn
        var dur int
        var str string
        for i := 0; i < 25*1e2; i++ {
            str, err = txnReader.ReadString('
')
            str = strings.TrimSuffix(str, "
")
            if err != nil {
                panic(err)
            }
            data = strings.Split(str, " ")
            txn.Amt, err = strconv.ParseFloat(data[1], 64)
            if err != nil {
                panic(err)
            }
            if err != nil {
                panic(err)
            }
            dur, err = strconv.Atoi(data[0])
            if err != nil {
                panic(err)
            }
            txn.Date = time.Now().Add(-time.Second * time.Duration(dur))
            txnChannel <- txn
        }
}

The other goroutine insertTxn, creates a reference to txn collection, and keep listening on the txnChannel channel, and writes the data it receives to the mongo collection.

func insertTxn(session *mgo.Session, txnChannel <-chan Txn) {
        txnColl := session.DB("happay").C("txns")
        for {
            select {
            case txn := <-txnChannel:
                if err := txnColl.Insert(txn).Error; err != nil {
                    panic(err)
                }
            }
        }
}

Now, the program panics with following reason:

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

I believe the issue might be that I am using the same struct again and again, but as I read that writing to a channel does copy by value, rather than by reference. So, it should work. Any help would be highly appreciated.

查看全部
dt102282
dt102282
2018/06/08 07:36
  • channel
  • segmentation-fault
  • mongodb
  • 点赞
  • 收藏
  • 回答
    私信
满意答案
查看全部

1个回复