#go #package #deadlock #channels
#Вперед #пакет #взаимоблокировка #Каналы
Вопрос:
Взаимоблокировка в каналах связи между двумя пакетами — Golang.
У меня есть два пакета, которые передаются по двум каналам. Один является основным, а другой имеет функцию. Когда я запускаю его, я получаю взаимоблокировку.
package main
import (
functionspackage "GoEjemplos/subFolder"
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
ChannelSendData := make(chan functionspackage.FunctionStruct, 1)
defer close(ChannelSendData)
data := functionspackage.FunctionStruct{
FieldOne: 3.56,
FieldTwo: 23,
}
ChannelSendData <- data
wg.Add(1)
go functionspackage.FunctionExt(ChannelSendData, amp;wg)
recibe := <-functionspackage.ChannelOutFunct
fmt.Println("channelOut: ", recibe)
close(functionspackage.ChannelOutFunct)
wg.Wait()
}
Другой пакет является
package functionspackage
import "sync"
type FunctionStruct struct {
FieldOne float64
FieldTwo int
}
var ChannelOutFunct chan float64
func FunctionExt(RecibeChan chan FunctionStruct, wg *sync.WaitGroup) (ChannelOutFunct chan float64) {
reciveData := <-RecibeChan
result := reciveData.FieldOne * float64(reciveData.FieldTwo)
ChannelOutFunct <- result
wg.Done()
return ChannelOutFunct
}
Это взаимоблокировка.
PS C:Go-ProjectsrcGoEjemplos> go run main.go
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive (nil chan)]:
main.main()
C:/Go-Project/src/GoEjemplos/main.go:32 0x13d
goroutine 19 [chan send (nil chan)]:
GoEjemplos/subFolder.FunctionExt(0xc0000d4000, 0xc0000a2070, 0xc0000c9f18)
C:/Go-Project/src/GoEjemplos/subFolder/functionsPackage.go:19 0x85
created by main.main
C:/Go-Project/src/GoEjemplos/main.go:30 0x11a
exit status 2
PS C:Go-ProjectsrcGoEjemplos>
Не могли бы вы объяснить мне, в чем проблема?
Спасибо!
Ответ №1:
Канал functionspackage.ChannelOutFunct
не инициализирован, поэтому он является нулевым каналом. Запись в нулевой канал или чтение из нулевого канала всегда будут блокироваться.
Комментарии:
1. Я ценю ваш ответ. В любом случае, мне нужно, если вы можете помочь мне немного больше. Я понимаю, что канал не инициализирован, и это вызывает ошибку. Но я не знаю, где я должен его инициализировать, потому что, насколько я понимаю, он уже был инициализирован в пакете functionspackage (var ChannelOutFunct chan float64) Если я удалю этот канал и инициализирую его в main, как это будет связано с возвратом функции, найденной в другом пакете? Приношу свои извинения за доставленные неудобства. Я пытаюсь научиться программированию на Go.
2. Он не инициализирован, он объявлен, поэтому он равен нулю. Вы можете объявить и инициализировать его:
var ChannelOutFunct = make(chan float64)
. Вы также можете инициализировать егоmain
. Это находится в другом пакете, здесь не имеет никакого значения.
Ответ №2:
Я заставил это работать. Это код
package main
import (
packagefunctions "GoEjemplos/subFolder"
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
var ChannelSendData = make(chan packagefunctions.FunctionStruct, 0)
defer close(ChannelSendData)
var ChanReturn = make(chan float64)
defer close(ChanReturn)
data := packagefunctions.FunctionStruct{
FieldOne: 3.56,
FieldTwo: 2,
}
wg.Add(1)
go func() { ChannelSendData <- data }()
wg.Add(1)
go func() {
ChanReturn = packagefunctions.FunctionExt(ChannelSendData, amp;wg)
recibeChanReturn := <-ChanReturn
fmt.Println("channelOut: ", recibeChanReturn)
wg.Done()
}()
wg.Wait()
}
другой пакет является
package packagefunctions
import (
"fmt"
"sync"
)
type FunctionStruct struct {
FieldOne float64
FieldTwo int
}
func FunctionExt(ChanIn chan FunctionStruct, wg *sync.WaitGroup) chan float64 {
reciveData, ok := <-ChanIn
if ok == false {
fmt.Println("channel closed")
}
var result float64
result = reciveData.FieldOne * float64(reciveData.FieldTwo)
var ChannelReturn = make(chan float64, 1)
defer close(ChannelReturn)
ChannelReturn <- result
wg.Done()
return ChannelReturn
}