@to_east

Конкурентность несколько вопросов?

Всех приветствую!
Спрошу, отталкиваясь от конкретной задачи. Вот мне необходимо загрузить относительно большой файл, и раскидать полученную информацию по структуре, чтобы это было синхронизованно и побыстрее.
И мне видится такой алгоритм:

1) Взять общее кол-во строк в файле, и разбить на кол-во потоков, примерно так:
https://play.golang.org/p/3DD453D1GNJ
2) Потом запустить потоки с интервалами строк, чтобы каждый поток обрабатывал свой интервал, причем чтобы читал построчно.
Так вот, вопрос: Какой более рациональный метод синхронизации использовать к этой задаче.
К примеру есть структура Data нужно сделать так, чтобы читать и писать в эту структуру мог только один поток в одно время. Делать блокировку в методах или можно как-то накладывать блокировку на саму структуру? По ходу написания поста, вспомнил то, как раз, организовывал пул потоков с очередями на Python, в принципе освобождает от того что я выше листинг запостил, наверное так и сделаю с пулом.
  • Вопрос задан
  • 166 просмотров
Пригласить эксперта
Ответы на вопрос 2
yellow79
@yellow79
Senior Software Engineer
Не надо ничего разбивать. Создай канал, в который будешь построчно писать строки из файла, так же создай воркеры, которые будут читать из этого канала и что-то делать с этой строкой, по окончании результат передавать в другой канал, для финальной обработки. Из этого последнего канала читает только один ридер и пишет в твою структуру Data.

Накидал примерчик, если что, спрашивай
Ответ написан
@to_east Автор вопроса
Andrey Tsvetkov,
Хорошо, спасибо за поддержку! Детальнее разберу твой пример для ясности.

<-- After some time -->
К сожалению твой пример вывалился с фатальной ошибкой
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        c:/Users/chapplin/go/src/example1/test.go:59 +0x3cf

goroutine 18 [chan receive]:
main.writer(0xc04202c0c0, 0xc042050070)
        c:/Users/chapplin/go/src/example1/test.go:23 +0x5e
created by main.main
        c:/Users/chapplin/go/src/example1/test.go:37 +0xf0
exit status 2
Для продолжения нажмите любую клавишу . . .

Но потом, закоментил последнюю строчку
// <- done
Код отработал без ошибок.
Тут вот дополнительный вопрос, по видимому sigfault в бесконечном цикле:
func writer(result <- chan string, done chan bool) {
	for line := range result {
		fmt.Println(line)
	}
	done <- true
}

Может необходимо дополнительную проверку, и выходить по break из цикла, типа такого:
func writer(result <- chan string, done chan bool) {
	for line := range result {
        if (<- done) == true {
            break
        }
		fmt.Println(line)
	}
	done <- true
}

И в завершении программы уже делать done <- true
И зачем вообще этот done нужен, если он определен а явного использования нет?
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы