Форкинг с QT - PullRequest
       27

Форкинг с QT

0 голосов
/ 07 мая 2018

использование QtCreator для создания более высокого интерфейса с программным обеспечением. В основном есть набор кнопок для настройки и ввода, запуск и остановка задания Кнопки, моя проблема возникает из-за бесконечного цикла, который замораживает отображение, поэтому я решил использовать fork (), чтобы цикл конкурировал с основной программой, а не потреблял все ресурсы (без многопоточности), но программа зависала :

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not
been called
[xcb] Aborting, sorry about that.
a.out: ../../src/xcb_io.c:274: poll_for_event: Assertion 
`!xcb_xlib_threads_sequence_lost' failed.

функция, вызывающая цикл, называется «ВКЛ», «ВЫКЛ» предполагается для завершения разветвленного процесса.

//in button 'ON' func
ps = fork();
if(getpid() == ps)
{
    while(1)
    {
        strcpy(word, charset(minlength, maxlength, N));
        ui->pass->setText(word);//operation on the display
        ....SNIP
    }
}

//In button 'OFF' func
if(getpid() == ps)
    exit(0);

Я действительно спрашиваю, как правильно запустить некоторое время (1) и иметь возможность разбить, выйти или вернуться из него, не останавливая окно с помощью QT, спасибо.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

В представленном коде я вижу одну большую проблему, которая вызывает ваше зависание: вы никогда не позволяете Qt ничего обрабатывать, пока находитесь в цикле. Вам нужно разрешить Qt запустить цикл обработки событий. Самый простой способ - использовать QApplication::processEvents() внутри цикла.

Я также не фанат цикла while(1) по нескольким причинам. Во-первых, он может питаться машинными циклами, ожидая, когда что-то произойдет. Я сомневаюсь, что вам действительно нужно выполнить код как можно быстрее, возможно, вам не помешает немного поспать в цикле.

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

void MyClass::on_pushButton_ON_clicked()
{
    MyClass::done = false;  // this is a class attribute
    while (!MyClass::done) {
        QApplication::processEvents();
        //...
    }
}

void MyClass::on_pushButton_OFF_clicked()
{
    MyClass::done = true;
}
0 голосов
/ 07 мая 2018

Возможно, вы потерпите крах здесь:

ui->pass->setText(word);//operation on the display  

как и в Qt, вы не можете напрямую изменять пользовательский интерфейс из потоков без пользовательского интерфейса. Только от механизма сигналов и слотов.

Правильный способ не заморозить пользовательский интерфейс - это, очевидно, вычислять длинные операции в другом потоке.

Вы можете достичь этого несколькими способами:

Один из них заключается в создании подкласса QObject класса для создания «рабочего объекта», который будет выполнять все тяжелые операции. Вы создаете новый QThread объект, который должен жить столько времени, сколько вам нужно. И используйте метод QObject::moveToThread, чтобы переместить созданный объект в новый поток. Для управления вашим рабочим объектом вы должны отправлять сигналы от объекта и вызывать его слоты также через механизм сигнальных слотов. Если вы вызываете их напрямую - они будут выполняться в потоке вызывающего (поэтому не выполняйте такие вещи, как worker-> startHeavyJob (); в потоке пользовательского интерфейса). Вместо этого отправьте сигнал в пользовательском интерфейсе (emit sigStartHeavyStuff ();) и подключите его к слоту вашего рабочего объекта (slotDoHeavyStuff ();)

если вы не хотите беспокоиться об этом (если операция довольно мала) - вы можете использовать QApplication :: processEvents () для обработки событий в цикле событий пользовательского интерфейса при переходе в бесконечный цикл while.

Другой способ - использовать QtConcurrentRun framework для запуска функции в отдельном потоке, который управляет собой. Потоки взяты из пула потоков и управляются Qt. Этот подход выглядит как то, что вы хотите сделать. Хотя вы все равно сможете получать доступ к объектам пользовательского интерфейса только через сигналы и слоты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...