gpt4 book ai didi

go - GopherJS 在 goroutine 中的死锁

转载 作者:行者123 更新时间:2023-12-01 22:15:58 26 4
gpt4 key购买 nike

为什么下面的代码会出现死锁?我正在尝试将 goroutine 中的某些内容返回到外部

package main

import (
"fmt"
"syscall/js"
"time"
)

func test(this js.Value, i []js.Value) interface{} {
done := make(chan string, 1)

go func() {
doRequest := func(this js.Value, i []js.Value) interface{} {
time.Sleep(time.Second)

return 0
}

js.Global().Set("doRequest", js.FuncOf(doRequest))
args := []js.Value{js.ValueOf("url")}
var x js.Value
doRequest(x, args)
done <- "true"
}()

aa := <-done
fmt.Println(aa)

return 0
}

func main() {
c := make(chan bool)
js.Global().Set("test", js.FuncOf(test))
<-c
}

当我在浏览器上运行它并调用 test() 时,将显示以下错误
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
.....

最佳答案

几乎就是它在错误消息中所说的内容。所有的 goroutine 都处于休眠状态。 main不启动任何东西,只是接收一个 channel ,所以它被阻塞了,并且没有其他 goroutines 正在运行,所以不可能 main可能会再次唤醒,因此运行时会出现 panic 。

如果我没记错的话,与常规 Go 不同,如果 main,GopherJS 不会关闭所有内容并退出。退出(部分原因是:这到底意味着什么?最接近 Go 程序的模拟是关闭网页!这有点糟糕。所以 GopherJS 不会那样做。)。所以你在做什么来保持main严格来说,在 GopherJS 中,活着不是必需的。

也就是说,如果你说(例如)time.Sleep(time.Hour)最后,当所有的 goroutine 都还在休眠时(严格来说),main最终会唤醒,运行时知道,所以在这种情况下它不会 panic 。

至于你的实际test功能,一旦你尝试了,你会得到一个相关的错误信息:Uncaught Error: runtime error: cannot block in JavaScript callback, fix by wrapping code in goroutine . test在 channel 上进行阻塞调用,而 GopherJS 不允许在直接从 Javascript 调用的函数中执行此操作,因此它会发生 panic 。 (当我在 playground 中运行它时,我也会得到 Uncaught TypeError: r is not a function ,但这只是早期错误的后果。)
我想你要做的是等待doRequest完成,打印值并返回,但这不起作用。为此,您需要使用 native Javascript promise 或其他一些异步机制。

关于go - GopherJS 在 goroutine 中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60208819/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com