Используйте подпрограмму go для инициализации нескольких сервисов - PullRequest
0 голосов
/ 03 февраля 2020

Пытаюсь ознакомиться с подпрограммами и 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()
}

Запускает службы, но затем barfs с ошибкой взаимоблокировки. Что я делаю не так?

1 Ответ

4 голосов
/ 03 февраля 2020

Похоже, что вы забыли позвонить wg.Done, когда закончите выполнение:

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

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

Без этого wg.Wait будет ждать бесконечно. Когда все процедуры завершатся, основная программа будет единственной программой, ожидающей в этой группе ожидания, поэтому тупик.

...