Russian Qt Forum
Июнь 16, 2024, 01:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Запуск процесса в отдельном треде (Linux only)  (Прочитано 9480 раз)
pashazz
Гость
« : Июнь 08, 2010, 12:00 »

Ситуация такая.... я разрабатываю программу winegame (http://winegame-project.ru) и столкнулся с проблемой.
Мне нужно запустить процесс wine так, чтобы GUI не фризился на это время. Это можно сделать с помощью QProcess::startDetached.

НО! мне нужно отследить, когда процесс завершится. Со startDetached это невозможно, поэтому сейчас используется start. А с ним GUI фризится.

Я пытался сделать  это на QtConcurrent... примерно так...

Код
C++ (Qt)
void runWine (QProcess *proc, QString comand)
{
proc->start (command);
proc->waitForFinished();
}
 
void WineProcess:run()
{
process = new QProcess (this);
//блабла, инициализирую QProcess и пр.
watcher->setFuture(QtConcurrent::run (runWine, process, QString ("wine blablabla")));
//присоединяю watcher к QProgressDialog, блабла
}
 
 

В итоге получалось так:
1) в консоль сыпалось: cannot create children (0000) for parent (00000) that is in different thread много раз
2)процесс запускался, но в текущем треде
3)после завершения процесса вылезал QProgressDialog, который нужно было отменить....

Как сделать правильно? - вот в чем вопрос.
Записан
Eol
Гость
« Ответ #1 : Июнь 08, 2010, 14:38 »

...
НО! мне нужно отследить, когда процесс завершится. Со startDetached это невозможно, поэтому сейчас используется start. А с ним GUI фризится.
...
А если воспользоваться startDetached, а для того, чтобы узнать, когда процесс завершился - воспользоваться стандартными сигналами QProcess'а? Конкретней: finished  ( int exitCode, QProcess::ExitStatus exitStatus ), stateChanged  ( QProcess::ProcessState newState ) или error  ( QProcess::ProcessError error ).
(взял с http://doc.trolltech.com/4.6/qprocess.html секция - signals)
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #2 : Июнь 08, 2010, 17:07 »

Я запускаю процесс через

bool QProcess::startDetached ( const QString & program, const QStringList & arguments, const QString & workingDirectory, qint64 * pid = 0 )   [static]

И сохраняю его pid. Потом по таймеру раз в полсекунды проверяю существование процесса с пидом pid.
« Последнее редактирование: Июнь 08, 2010, 17:09 от Alex Custov » Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #3 : Июнь 08, 2010, 17:10 »

А если воспользоваться startDetached, а для того, чтобы узнать, когда процесс завершился - воспользоваться стандартными сигналами QProcess'а?

startDetached() - статический метод
Записан
Eol
Гость
« Ответ #4 : Июнь 08, 2010, 21:51 »

startDetached() - статический метод
Согласен, натупил, прошу прощения.

Касательно топика: я воспроизвел простенький проект с GUI, при нажатии на кнопочку он запускает процесс /usr/bin/sleep 5, и подключает его сигнал - finished(...) к своему слоту, по которому он на GUI выводит что-то вроде Finished. Так вот, между Started и Finished у меня интерфейс не виснет. ЧЯДНТ?

Код
C++ (Qt)
...
 
   proc = new QProcess();
   connect(proc, SIGNAL(finished(int,QProcess::ExitStatus)),
           this, SLOT(slotFinished(int,QProcess::ExitStatus)));
...
 
void MainWindow::startProcess()
{
   ui->textBrowser->append("Starting process...");
   proc->start("/usr/bin/sleep 5");
}
 
void MainWindow::slotFinished(int, QProcess::ExitStatus)
{
   ui->textBrowser->append("Finished process");
}
 
 

Насколько я понимаю, он по дефолту тоже запускает в бэкграунде, а у pashazz виснет из-за waitForFinished()?
Записан
pashazz
Гость
« Ответ #5 : Июнь 08, 2010, 21:53 »

Дело в том, что мне надо обязательно дождаться завершения процесса и ничего не делать, пока он завершится.
Записан
pashazz
Гость
« Ответ #6 : Июнь 08, 2010, 21:59 »

Ладно, завтра сделаю чего-нибудь с QEventLoop
Записан
BRE
Гость
« Ответ #7 : Июнь 08, 2010, 22:14 »

Дело в том, что мне надо обязательно дождаться завершения процесса и ничего не делать, пока он завершится.
Ладно, завтра сделаю чего-нибудь с QEventLoop
Для чего?
Есть же:
bool QProcess::waitForFinished ( int msecs = 30000 )
Записан
pashazz
Гость
« Ответ #8 : Июнь 09, 2010, 03:08 »

вы вообще тред читали?
Записан
BRE
Гость
« Ответ #9 : Июнь 09, 2010, 07:17 »

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

Код
C++ (Qt)
void MainWindow::startProcess()
{
QEventLoop loop;
 
WaitDialog dlg;
connect( &dlg, SIGNAL( canceled() ), &loop, SLOT( quit() ) );
 
QProcess proc;
connect( &proc, SIGNAL( finished(int,QProcess::ExitStatus) ), &loop, SLOT( quit() ) );
 
dlg.show();
proc.start( ... );
 
loop.exec();
}
 
Записан
AlekseyK
Гость
« Ответ #10 : Декабрь 18, 2010, 20:36 »

Цитата: Qt Documentation
Synchronous Process API
QProcess provides a set of functions which allow it to be used without an event loop, by suspending the calling thread until certain signals are emitted:
  • waitForStarted() blocks until the process has started.
  • waitForReadyRead() blocks until new data is available for reading on the current read channel.
  • waitForBytesWritten() blocks until one payload of data has been written to the process.
  • waitForFinished() blocks until the process has finished.
Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.273 секунд. Запросов: 22.