首页 > 解决方案 > 使用 goroutine 初始化多个服务

问题描述

试图让自己熟悉子例程和整体 Go,我正在尝试编写一个脚本,该脚本基本上将启动我的 django 应用程序的所有服务sync.WaitGroup并保持它们运行,直到我手动终止 Go 脚本,这就是为什么我没有该intitialize()功能实际上告诉等待组进程已完成。收到可怕的fatal error: all goroutines are asleep - deadlock!消息。

 func main() {
    var wg sync.WaitGroup
    os.Chdir("/home/Projects/djangoapp")
    cc := []cmds{cmds{
        name:  "django",
        cmdsl: []string{"/home/Projects/djangoapp/env/bin/python", "manage.py", "runserver"},
    },
        cmds{
            name:  "celeryd",
            cmdsl: []string{"/home/Projects/djangoapp/env/bin/celery", "-A", "djangoapp", "worker", "-l", "INFO", "-S", "django"},
        },
    }

    for x := 0; x < 2; x++ {
        wg.Add(1)
        fmt.Println("starting up", cc[x].name)
        go initialize(cc[x])
    }
    wg.Wait()
}

func initialize(ccmds cmds) {
    cmd := exec.Command(ccmds.cmdsl[0], ccmds.cmdsl[1:]...)
    cmd.Env = append(os.Environ(), "DJANGO_SETTINGS_MODULE=articleadmin.settings.default")

    fmt.Println("initializing", ccmds.name)
    cmd.Start()
    fmt.Println("started", ccmds.name)
    cmd.Wait()
}

它启动服务,但随后出现死锁错误。我究竟做错了什么?

标签: gosubroutine

解决方案


看起来你wg.Done在 goroutine 完成后忘记调用:

 go initialize(&wg,cc[x])
...

func initialize(wg *sync.WaitGroup,ccmds cmds) {
  defer wg.Done()
  ...
}

没有那个,wg.Wait将无限期地等待。当所有的 goroutine 都终止时,主 goroutine 将是唯一等待该 WaitGroup 的 goroutine,因此死锁。


推荐阅读