des1roer
@des1roer
ученье - свет, а неученье - приятный полумрак

Golang Stepik 3.9 Параллелизм ч.2 как решить?

https://stepik.org/lesson/345547/step/14?unit=329291

Вам необходимо написать функцию calculator следующего вида:

func calculator(arguments <-chan int, done <-chan struct{}) <-chan int
В качестве аргумента эта функция получает два канала только для чтения, возвращает канал только для чтения.

Через канал arguments функция получит ряд чисел, а через канал done - сигнал о необходимости завершить работу. Когда сигнал о завершении работы будет получен, функция должна в выходной (возвращенный) канал отправить сумму полученных чисел.

Функция calculator должна быть неблокирующей, сразу возвращая управление.

Выходной канал должен быть закрыт после выполнения всех оговоренных условий, если вы этого не сделаете, то превысите предельное время работы.

package main

import (
	"fmt"
)

func main() {
	arguments := make(chan int)
	done := make(chan struct{})
	result := calculator(arguments, done)
	for i := 0; i < 10; i++ {
		arguments <- 1
	}
	close(done)
	fmt.Println(<-result)
}

func calculator(arguments <-chan int, done <-chan struct{}) <-chan int {
	output := make(chan int)
	var x int

	go func(output chan int) {
		defer close(output)
		for {
			select { // Оператор select
			case <-arguments: // Ждет, когда проснется гофер
				x += <-arguments
				output <- x
				fmt.Println(x)
			case <-done: // Ждет окончания времени
				return
			}
		}

	}(output)

	return output
}


PS C:\proj> go build .\main.go; .\main.exe
1
2
3
4
5
0
PS C:\proj> go build .\main.go; .\main.exe
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
C:/proj/main.go:14 +0x6a

goroutine 6 [chan send]:
main.calculator.func1(0xc00005c120)
C:/proj/main.go:30 +0xcf
created by main.calculator
C:/proj/main.go:24 +0x10d
  • Вопрос задан
  • 546 просмотров
Решения вопроса 1
@falconandy
package main

import (
	"fmt"
)

func main() {
	arguments := make(chan int)
	done := make(chan struct{})
	result := calculator(arguments, done)
	for i := 0; i < 10; i++ {
		arguments <- 1
	}
	close(done)
	fmt.Println(<-result)
}

func calculator(arguments <-chan int, done <-chan struct{}) <-chan int {
	output := make(chan int)

	go func(output chan int) {
		defer close(output)

		var x int
	Loop:
		for {
			select { // Оператор select
			case arg, ok := <-arguments: // Ждет, когда проснется гофер
				if !ok {
					break Loop
				}
				x += arg
				fmt.Println(x)
			case <-done: // Ждет окончания времени
				break Loop
			}
		}
		output <- x
	}(output)

	return output
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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