英文:
Golang HelloActor I fatal error: all goroutines are asleep - deadlock
问题
我有以下代码来测试使用Go 1.18的actor模型:
package main
import (
"fmt"
"sync"
"github.com/AsynkronIT/protoactor-go/actor"
)
// Actor
type helloActor struct{}
func (*helloActor) Receive(context actor.Context) {
switch msg := context.Message().(type) {
case int:
fmt.Println(msg)
}
}
func main() {
system := actor.NewActorSystem()
props := actor.PropsFromProducer(func() actor.Actor { return &helloActor{} })
pid := system.Root.Spawn(props)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
这段代码是由我的教授编写的,但由于某种原因,我收到了致命错误消息。其他遇到这个问题的人通常没有(正确地)关闭通道,但是actor模型不使用任何通道。通过调试,我发现程序在wg.Wait()
处崩溃。在Wait
方法中调用了semaquire
函数,但程序随后崩溃。
以下是精确的错误输出:
PS C:\Users\mytho\go\Verteilte Softwaresysteme\labing\ob-22ss> go run Code/proto.actor/helloworld/helloworld.go
42
42
42
42
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x10?)
C:/Program Files/Go/src/runtime/sema.go:56 +0x25
sync.(*WaitGroup).Wait(0xc000223320?)
C:/Program Files/Go/src/sync/waitgroup.go:136 +0x52
main.main()
C:/Users/mytho/go/Verteilte Softwaresysteme/labing/ob-22ss/Code/proto.actor/helloworld/helloworld.go:34 +0x14f
goroutine 6 [chan receive]:
github.com/AsynkronIT/protoactor-go/log.(*ioLogger).listenEvent(0xc000124480)
C:/Users/mytho/go/pkg/mod/github.com/!asynkron!i!t/protoactor-go@v0.0.0-20220403033403-f313dba2c418/log/string_encoder.go:57 +0x6d
created by github.com/AsynkronIT/protoactor-go/log.init.1
C:/Users/mytho/go/pkg/mod/github.com/!asynkron!i!t/protoactor-go@v0.0.0-20220403033403-f313dba2c418/log/string_encoder.go:39 +0x10a
exit status 2
注意:当调试helloactor.go
时,会显示四个"42"消息。当运行它时,只会显示错误消息。
英文:
I have the following Code to test the actor-model with Go 1.18
package main
import (
"fmt"
"sync"
"github.com/AsynkronIT/protoactor-go/actor"
)
// Actor
type helloActor struct{}
func (*helloActor) Receive(context actor.Context) {
switch msg := context.Message().(type) {
case int:
fmt.Println(msg)
}
}
func main() {
system := actor.NewActorSystem()
props := actor.PropsFromProducer(func() actor.Actor { return &helloActor{} })
pid := system.Root.Spawn(props)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
system.Root.Send(pid, 42)
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
This Code was written by my professor but for some reason I get the fatal error message. Other people who have this problem often don't (properly) close channels but the actor-model does not use any.
Through debugging I found out that the programm crashes at wg.Wait(). Within the Wait-method is a call of the semaquire function. But then the programm crashes.
Here is the exact error output:
PS C:\Users\mytho\go\Verteilte Softwaresysteme\labing\ob-22ss> go run Code/proto.actor/helloworld/helloworld.go
42
42
42
42
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x10?)
C:/Program Files/Go/src/runtime/sema.go:56 +0x25
sync.(*WaitGroup).Wait(0xc000223320?)
C:/Program Files/Go/src/sync/waitgroup.go:136 +0x52
main.main()
C:/Users/mytho/go/Verteilte Softwaresysteme/labing/ob- 2
2ss/Code/proto.actor/helloworld/helloworld.go:34 +0x14f
goroutine 6 [chan receive]:
github.com/AsynkronIT/protoactor-go/log.(*ioLogger).listenEvent(0xc000124480)
C:/Users/mytho/go/pkg/mod/github.com/!asynkron!i!t/protoactor-go@v0.0.0-
20220403033403-f313dba2c418/log/string_encoder.go:57 +0x6d
created by github.com/AsynkronIT/protoactor-go/log.init.1
C:/Users/mytho/go/pkg/mod/github.com/!asynkron!i!t/protoactor-go@v0.0.0-
20220403033403-f313dba2c418/log/string_encoder.go:39 +0x10a
exit status 2
NOTE: the four "42" messages are only shown when the helloactor.go is debugged. When it is being runned it only shows the error-message.
答案1
得分: 1
var wg sync.WaitGroup
wg.Add(1)
wg.Done()
wg.Wait()
你没有调用wg.Done()
来减少WaitGroup计数器。
PS:sync.WaitGroup
用于在主goroutine完成之前等待其他goroutine完成。但在你的代码中,你没有创建任何其他的goroutine,所以它没有用处。
参考文档:https://pkg.go.dev/sync#WaitGroup
英文:
var wg sync.WaitGroup
wg.Add(1)
wg.Done()
wg.Wait()
You are not calling wg.Done()
to decrement the WaitGroup counter.
PS: sync.WaitGroup
is used to wait for goroutines to finish before the main goroutine completes. But in your code, you are not spawning any other goroutine so it has no use.
For reference, check https://pkg.go.dev/sync#WaitGroup
答案2
得分: 0
wg.Wait()
在没有wg.Done()
的情况下会永远休眠。
看起来你想要一个阻塞的效果,对吗?
只需使用fmt.Scanf
函数,它会一直阻塞IO,直到你输入回车键。
例如:
fmt.Println("输入回车键退出")
fmt.Scanf(" ")
英文:
The wg.Wait()
will sleep forever without wg.Done()
.
It seems that you want a blocking, right?
Just use the fmt.Scanf
function, it will keep io blocking until you type Enter
.
For example:
fmt.Println("type enter to exit")
fmt.Scanf(" ")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论