Задать вопрос
@smarisov666

Как исправить ошибку с Valchan горутины?

package main

import (
	"bufio"
	"encoding/json"
	"log"
	"os"
	"strings"
	"sync"
)

type Config struct {
	First_file  string `json:"first_file"`
	Second_file string `json:"second_file"`
	Out_file    string `json:"out_file"`
	Count_check int    `json:"count_check"`
}

func LoadConfiguration(file string) Config {
	var config Config
	configFile, err := os.Open(file)
	defer configFile.Close()
	if err != nil {
		log.Println(err.Error())
	}
	jsonParser := json.NewDecoder(configFile)
	jsonParser.Decode(&config)
	return config
}

func scanFiles(file1, file2 *bufio.Scanner, config Config) {
	scanWg := new(sync.WaitGroup)
	scanWg.Add(2)

	file1SubStrings := make(map[string]string)
	file2SubStrings := make(map[string]string)

	go func() {
		var substr []string
		for file1.Scan() {
			substr = strings.Split(file1.Text(), ":")
			if len(substr) > 0 {
				file1SubStrings[substr[1]] = substr[0]
			}
		}
		scanWg.Done()
	}()

	go func() {
		var substr []string
		for file2.Scan() {
			substr = strings.Split(file2.Text(), ":")
			if len(substr) > 0 {
				file2SubStrings[substr[0]] = substr[1]
			}
		}
		scanWg.Done()
	}()

	scanWg.Wait()

	wg := new(sync.WaitGroup)
	valChan := make(chan struct{ k, v string })
	if file2SubStrings != nil && file1SubStrings != nil {
		for i := 0; i < config.Count_check; i++ {
			wg.Add(1)
			go findIntersections(valChan, file2SubStrings, wg, config)
		}
	
		for k, v := range file1SubStrings {
			valChan <- struct{ k, v string }{k: k, v: v}
		}
		close(valChan)
		wg.Wait()
	}
}

func findIntersections(file1Values chan struct{ k, v string }, file2 map[string]string, wg *sync.WaitGroup, config Config) {
	for {
		file1, ok := <-file1Values

		if !ok {
			wg.Done()
			return
		}

		if file2Value, ok := file2[file1.k]; ok {
			f, err := os.OpenFile(config.Out_file, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
			if err != nil {
				log.Fatalln("error files")
				return
			}
			f.WriteString(file1.v + ":" + file2Value + "\n")
		}
	}
}

func main() {
	config := LoadConfiguration("./config.json")

	file1, err := os.Open(config.First_file)
	if err != nil {
		log.Fatalln("error")
	}
	defer file1.Close()
	file1Scanner := bufio.NewScanner(file1)

	file2, err := os.Open(config.Second_file)
	if err != nil {
		log.Fatalln("error")
	}
	defer file2.Close()
	file2Scanner := bufio.NewScanner(file2)

	scanFiles(file1Scanner, file2Scanner, config)

	if err := file1Scanner.Err(); err != nil {
		log.Fatalln(err)
	}

	if err := file2Scanner.Err(); err != nil {
		log.Fatalln(err)
	}
}

Сама ошибка:
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.scanFiles(0xc000108000, 0xc000108080, {{0xc000016220, 0xe}, {0xc000016230, 0xd}, {0xc000016240, 0xd}, 0x0})
	c:/Users/fazuq/Desktop/back in progmramming/golang-reader-files/index.go:71 +0x3ae
main.main()
	c:/Users/fazuq/Desktop/back in progmramming/golang-reader-files/index.go:115 +0x2d8
exit status 2
  • Вопрос задан
  • 63 просмотра
Подписаться 2 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
OrlovEvgenii
@OrlovEvgenii
golang developer / DevOps
Ошибка связана с тем, что вы пытаетесь отправить данные по каналу valChan, но все горутины уже завершили свою работу.

func scanFiles(file1, file2 *bufio.Scanner, config Config) {
    scanWg := new(sync.WaitGroup)
    scanWg.Add(2)

    file1SubStrings := make(map[string]string)
    file2SubStrings := make(map[string]string)

    go func() {
        var substr []string
        for file1.Scan() {
            substr = strings.Split(file1.Text(), ":")
            if len(substr) > 0 {
                file1SubStrings[substr[1]] = substr[0]
            }
        }
        scanWg.Done()
    }()

    go func() {
        var substr []string
        for file2.Scan() {
            substr = strings.Split(file2.Text(), ":")
            if len(substr) > 0 {
                file2SubStrings[substr[0]] = substr[1]
            }
        }
        scanWg.Done()
    }()

    scanWg.Wait()

    if file2SubStrings != nil && file1SubStrings != nil {
        wg := new(sync.WaitGroup)
        valChan := make(chan struct{ k, v string })

        for i := 0; i < config.Count_check; i++ {
            wg.Add(1)
            go findIntersections(valChan, file2SubStrings, wg, config)
        }

        for k, v := range file1SubStrings {
            valChan <- struct{ k, v string }{k: k, v: v}
        }

        close(valChan)
        wg.Wait()
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы