Запуск отдельного процесса в Qt и работа с портами - PullRequest
4 голосов
/ 12 сентября 2011

Возможно, у меня неправильное понимание того, как работает Qt startDetached(), но я наблюдаю проблему, когда у меня есть приложение, которое функционирует как удаленный модуль запуска.

Программа запуска запускает процессы, используя startDetached, который, как я думал, полностью отделяет приложение запуска от нового процесса. Однако что-то подозрительное происходит с портами, которые использует пусковая установка. Кажется, что порожденные процессы также прослушивают эти же порты, несмотря на то, что они не используют сетевой код.

Проблема заключается в том, что когда я завершаю процесс запуска, я не могу перезапустить его, потому что порожденные процессы, похоже, все еще используют порт, на котором пытается запустить модуль запуска.

Мой вопрос: что я делаю не так? Есть ли лучший способ для удаленного агента запускать процессы, которые также не подключаются к портам?

Это в среде Linux.

РЕДАКТИРОВАТЬ: Ошибка Qt В итоге я воспользовался этим исправлением ошибки и просто перекомпилировал Qt. Казалось бы, работа!

1 Ответ

1 голос
/ 12 сентября 2011

Согласно этому сообщению об ошибке , все дескрипторы файлов и сокетов, открытые Qt (QFile, QTcpSocket ...), помечены FD_CLOEXEC, чтобы предотвратить их совместное использование с дети-процессы.

Итак, если вы открываете сокеты без Qt, вам, вероятно, следует сделать то же самое.

Редактировать

Я открываю сокеты с каркасом ICE.

Вы могли бы:

  • попробуйте цикл, указанный в , как установить по умолчанию close-on-exec , чуть ниже строки /* please don't do this */ или
  • вставьте первую строку той же ссылки в функцию createSocket из Ice/cpp/src/Ice/Network.cpp, если вы можете изменить исходный код ICE (и перераспределить ваши изменения, если вы используете их лицензию GPL), или
  • использовать процесс-оболочку, например daemonize , чтобы закрыть все дескрипторы перед запуском настоящий ребенок-процесс.
    Возможно, что-то более простое, например, следующий код, тоже может работать (он компилируется и работает нормально, но я не тестировал его с открытыми сокетами):

    #include <unistd.h>
    #include <iostream>
    #include <cstring>
    #include <cerrno>
    
    int main(int argc, char**argv)
    {
        // close all descriptors except stdout/stdin/stderr
        int maxfd = sysconf(_SC_OPEN_MAX);
        for(int fd = 3; fd < maxfd; fd++)
            close(fd);
    
        // pass all the program arguments except the wrapper name
        execve(argv[1], &argv[1], environ);
    
        // exec() only returns if an error occurred
        std::cerr << strerror(errno) << std::endl;
        return 1;
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...