All goroutines are asleep - deadlock!

I read this and this and this but none of them solving my issue.

I’m trying to read 2 files async, so I wrote the below:

//readlines.go
package main

import (
	"bufio"
	"os"
)

// readLines reads a whole file into memory
// and returns a slice of its lines.
func readLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

And calling it as:

package main

import (
	"fmt"
	"os"

	"github.com/gocarina/gocsv"
)

func (s *stocks) Read() {
	fmt.Println("Reading")
	stockFile, err := os.OpenFile("current_invenory.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer stockFile.Close()
	stocks := []systemStock{}
	if err := gocsv.UnmarshalFile(stockFile, &stocks); err != nil { // Load stocks from file
		panic(err)
	}

	*s = stocks
}

package main

import (
	"fmt"
	"os"

	"github.com/gocarina/gocsv"
)

func (t *transactions) Read() {
	fmt.Println("Reading")
	trxFile, err := os.OpenFile("current_transactions.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer trxFile.Close()
	trx := []systemTransactions{}
	if err := gocsv.UnmarshalFile(trxFile, &trx); err != nil { // Load stocks from file
		panic(err)
	}

	*t = trx
}

The above working very fine with:

	stock := stocks{} 
	trx := transactions{}

	stock.Read()
	trx.Read()
	for _, s := range stock {
			fmt.Println("Hello", s.Code)
	}

But give the error fatal error: all goroutines are asleep - deadlock! when I tried to read them as:

	cs, ct := readData()

	for _, s := range cs {
		fmt.Println("Hello", s.Code)
	}

	for _, t := range ct {
		fmt.Println("Hello trx of ", t.Code)
	}

Using

import "sync"

//func readData(cs chan stocks, ct chan transactions) (stocks, transactions) {
func readData() (stocks, transactions) {
	var wg sync.WaitGroup
	defer wg.Done()

	stock := stocks{}
	trx := transactions{}

	wg.Add(1)
	go stock.Read()
	wg.Add(1)
	go trx.Read()

	wg.Wait()

	return stock, trx
}

So the error is related for something wrong I made (or do not understand) in the last block~

Hi, @hyousef, You’re (correctly) adding 1 to the wait group when you start reading from each CSV, bringing the wait group’s internal counter to 2, but wg.Wait() will wait until that counter goes down to zero and you don’t have any calls to wg.Done() to do that. I recommend changing go stock.Read() to:

go func() {
    defer wg Done()
    stock.Read()
}()

And then do the same thing with the transactions.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.