- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
下面的代码适用于硬编码的 JSON 数据,但是当我从文件中读取 JSON 数据时不起作用。我收到 fatal error: all goroutines are sleep - deadlock
错误,当使用 sync.WaitGroup
。
使用硬编码 JSON 数据的工作示例:
package main
import (
"bytes"
"fmt"
"os/exec"
"time"
)
func connect(host string) {
cmd := exec.Command("ssh", host, "uptime")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s: %q\n", host, out.String())
time.Sleep(time.Second * 2)
fmt.Printf("%s: DONE\n", host)
}
func listener(c chan string) {
for {
host := <-c
go connect(host)
}
}
func main() {
hosts := [2]string{"user1@111.79.154.111", "user2@111.79.190.222"}
var c chan string = make(chan string)
go listener(c)
for i := 0; i < len(hosts); i++ {
c <- hosts[i]
}
var input string
fmt.Scanln(&input)
}
输出:
user@user-VirtualBox:~/go$ go run channel.go
user1@111.79.154.111: " 09:46:40 up 86 days, 18:16, 0 users, load average: 5"
user2@111.79.190.222: " 09:46:40 up 86 days, 17:27, 1 user, load average: 9"
user1@111.79.154.111: DONE
user2@111.79.190.222: DONE
不起作用 - 读取 JSON 数据文件的示例:
package main
import (
"bytes"
"fmt"
"os/exec"
"time"
"encoding/json"
"os"
"sync"
)
func connect(host string) {
cmd := exec.Command("ssh", host, "uptime")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s: %q\n", host, out.String())
time.Sleep(time.Second * 2)
fmt.Printf("%s: DONE\n", host)
}
func listener(c chan string) {
for {
host := <-c
go connect(host)
}
}
type Content struct {
Username string `json:"username"`
Ip string `json:"ip"`
}
func main() {
var wg sync.WaitGroup
var source []Content
var hosts []string
data := json.NewDecoder(os.Stdin)
data.Decode(&source)
for _, value := range source {
hosts = append(hosts, value.Username + "@" + value.Ip)
}
var c chan string = make(chan string)
go listener(c)
for i := 0; i < len(hosts); i++ {
wg.Add(1)
c <- hosts[i]
defer wg.Done()
}
var input string
fmt.Scanln(&input)
wg.Wait()
}
输出
user@user-VirtualBox:~/go$ go run deploy.go < hosts.txt
user1@111.79.154.111: " 09:46:40 up 86 days, 18:16, 0 users, load average: 5"
user2@111.79.190.222: " 09:46:40 up 86 days, 17:27, 1 user, load average: 9"
user1@111.79.154.111 : DONE
user2@111.79.190.222: DONE
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc210000068)
/usr/lib/go/src/pkg/runtime/sema.goc:199 +0x30
sync.(*WaitGroup).Wait(0xc210047020)
/usr/lib/go/src/pkg/sync/waitgroup.go:127 +0x14b
main.main()
/home/user/go/deploy.go:64 +0x45a
goroutine 3 [chan receive]:
main.listener(0xc210038060)
/home/user/go/deploy.go:28 +0x30
created by main.main
/home/user/go/deploy.go:53 +0x30b
exit status 2
user@user-VirtualBox:~/go$
HOSTS.TXT
[
{
"username":"user1",
"ip":"111.79.154.111"
},
{
"username":"user2",
"ip":"111.79.190.222"
}
]
最佳答案
Go 程序在 main 函数结束时结束。
Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
因此,您需要等待 goroutine 完成。常见的解决方案是使用 sync.WaitGroup对象。
同步goroutine的最简单代码:
package main
import "fmt"
import "sync"
var wg sync.WaitGroup // 1
func routine() {
defer wg.Done() // 3
fmt.Println("routine finished")
}
func main() {
wg.Add(1) // 2
go routine() // *
wg.Wait() // 4
fmt.Println("main finished")
}
用于同步多个 goroutines
package main
import "fmt"
import "sync"
var wg sync.WaitGroup // 1
func routine(i int) {
defer wg.Done() // 3
fmt.Printf("routine %v finished\n", i)
}
func main() {
for i := 0; i < 10; i++ {
wg.Add(1) // 2
go routine(i) // *
}
wg.Wait() // 4
fmt.Println("main finished")
}
WaitGroup 按执行顺序使用。
* 实际参数为evaluated before starting new gouroutine .因此需要在 wg.Add(1)
之前显式评估它们,这样可能出现 panic 的代码就不会留下增加的计数器。
使用
param := f(x)
wg.Add(1)
go g(param)
而不是
wg.Add(1)
go g(f(x))
关于GO语言: fatal error: all goroutines are asleep - deadlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26927479/
我正在尝试制作一个代码来扫描一个文件夹链接我的所有文件,并根据他的大小制作一个“前 10 名”,并根据他的内容和他的名字制作一个正则表达式。文件。根据内容,我使用 goroutines 创建 chan
我有一个在 for 循环中运行的 goroutine: func main(){ for _, i := range x{ go httpR
为什么像这样简单的东西不起作用? c1 := make(chan string) c1 <- "foo" fmt.Println(<-c1) 但是如果我把它放在一个 go routine 中它会起作用
下面的代码 ( http://play.golang.org/p/ikUtdoKOo5 ) 应该向多个客户端广播一条消息。但它不起作用,我不明白为什么。 package main import "fm
给定以下简单的 Go 程序 package main import ( "fmt" ) func total(ch chan int) { res := 0 for iter
在继续工作之前,我一直遵循检查 channel 中是否有任何内容的模式: func consume(msg <-chan message) { for { if m, ok := <-ms
我的 dicerolling 程序发生了一次奇怪的崩溃。它工作正常,但最后它总是说: fatal error :所有 goroutine 都处于休眠状态 - 死锁! goroutine 1 [chan
TL; DR:all goroutines are asleep, deadlock!的一种典型情况,但无法弄清 我正在解析Wiktionary XML转储以构建单词数据库。我将每篇文章的文本解析推迟
练习来自:https://tour.golang.org/concurrency/10 描述: In this exercise you'll use Go's concurrency feature
我有以下 Go 代码 package main import ( "fmt" "math/rand" ) const ( ROCK int = iota PAPER
努力学习并发。我遇到了以下错误: fatal error: all goroutines are asleep - deadlock! 我被告知要添加一个 WaitGroup 和一个关闭 channe
package main import ( "fmt" "os" "os/exec" "bufio" "reflect" ) func runTheComman
我想用 Go 开发一个简单的电子邮件发送器,但遇到了一些问题,这是我的实际代码: package main import ( "flag" "sync" "fmt" ) var
下面的代码适用于硬编码的 JSON 数据,但是当我从文件中读取 JSON 数据时不起作用。我收到 fatal error: all goroutines are sleep - deadlock 错误
我正在做一些实验。下面是我的代码。 package main import ( "fmt" "time" ) func main(){ var a chan int a = make(
我试图了解 channel 是如何运作的。我有这个例子: import ( "fmt" "runtime" "time" ) func greet(c chan string)
我正在使用 Golang 构建护理模拟,但遇到了死锁问题。 Goroutines 用于代表每个赛车手。 这个想法是,一旦赛车手达到目标,就会使用一个 channel 来传达哪个赛车手获胜。 谁能发现我
我正在尝试重现问题并使用以下代码得出最小用例。如果我关闭所有 channel (绕过 i == 0 测试),一切都会按预期进行。 Wg 状态递减并触发完成,main 退出正常。当我(故意)跳过关闭其中
这是引用 Go 编程语言中的以下代码 - 第 8 章 p.238 从下面复制自 this链接 // makeThumbnails6 makes thumbnails for each file rec
我想用 Python 将 mime/multipart 消息写入标准输出,然后使用 mime/multipart 包在 Golang 中读取该消息。这只是一个学习练习。 我尝试模拟 this exam
我是一名优秀的程序员,十分优秀!