2015-09-18 4 views
3

Я пишу небольшую утилиту обновления, которая вызывается из основной программы. Основная программа заканчивается сразу после вызова и позволяет обновить копию всех обновленных файлов, а затем она должна перезапустить основную программу. Однако этот последний бит начинает давать мне головную боль.Запустите приложение и забудьте в переносном режиме

Я могу запустить программу с std::system (я знаю, небезопасно, но портативен) просто отлично, но затем программа обновления просто висит там, ожидая завершения основной программы. Я искал способы позвонить по телефону пожар & забудьте, и потоки кажутся лучшими.

Однако это:

std::system("app"); 

висит Апдейтер, как он ожидает возвращения из system. В то время как это:

std::thread(std::system, "app").detach(); 

ни вариант

std::thread t(std::system, "app"); 
t.detach(); 

, кажется, сделать что-нибудь. Но когда я присоединяюсь нить:

std::thread t(std::system, "app"); 
t.join(); 

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

+1

Какого уровень переносимости вам нужно (например, какие платформы представляют интерес)? –

+0

@JasonR Основное приложение - приложение Qt, и я нацелен на 3 платформы Qt: рабочий стол, linux и mac ... – Resurrection

+1

Не подходит QProcess? –

ответ

2

Любой поток, будь то отдельные или нет, умрет, если его завершения процесса (на большинстве системы). Дайте некоторое время до окончания выполнения программы обновления и нить может быть в состоянии фактически сделать вызов:

#include <chrono> 
#include <cstdlib> 
#include <thread> 

void do_app() { 
    std::system("app"); 
} 

int main() { 
    std::thread(do_app).detach(); 
    std::this_thread::sleep_for(std::chrono::seconds(2)); 
} 
+0

Блестящий. :-) На самом деле это трюк ... Я не думал, что это будет проблемой, поскольку я прочитал путаную информацию о том, «что происходит с отдельными потоками после основных возвратов», причем некоторые утверждают, что он убит (как это, по-видимому, имеет место), а некоторые - нет. – Resurrection

+0

Это потому, что стандарт фактически не определяет, что происходит с отсоединенным потоком, когда заканчивается выполнение главной программы: каждая система может что-то делать. Конечно, возможно, что какая-то экзотическая система поддерживает выполнение потока. Большинство нет. –

1

Я бы просто использовал блоки ifdef вокруг различных реализаций. Для Windows вы можете использовать CreateProcess, Linux (и, возможно, Mac) поддерживает методы POSIX popen/fork.

std :: system на самом деле не делает вашу программу переносимой, как правило, синтаксис для вызова вещей в оболочке немного отличается от платформы к платформе, и в любом случае вы получаете код, зависящий от платформы.

Вот подробный учебник о том, как это сделать в Linux: http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

И для Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

+0

Спасибо, я посмотрю. Различные методы вызова могут быть решены путем передачи фактической команды для вызова из основной программы при вызове программы обновления. – Resurrection

Смежные вопросы