Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt] потоки: пуск/останов


Автор: Elfet 20.1.2010, 12:08
Ясно, спасибо!

Можете ещё подсказать кое-что? Не хочу отдельную тему создавать. 

У меня на форме есть ещё две кнопки: Пауза и Стоп.
Каким образом можно приостановить выполнение процесса и заново его запустить?

Я сделал так:
Код

void IterationThread::run()
{
    is_runing = true;
    for(; i <= 100; i++)
    {
        emit Progress(i);
        msleep(100);
        if(!is_runing)
        {
            return;
        }
    }
}

void IterationThread::Pause()
{
    is_runing = false;
}


И подключил слот Pause() к нужной кнопке на форме. А обратно запустить вычисления опять через run():
Код

iterationThread->run();


Нормально ли так?

Автор: andrew_121 20.1.2010, 12:12
Цитата(Elfet @  20.1.2010,  12:08 Найти цитируемый пост)
Каким образом можно приостановить выполнение процесса и заново его запустить?

никаким.
можно в метод потока вставить бесконечный цикл, и его останавливать/возобновлять.

Добавлено через 1 минуту и 5 секунд
Цитата(Elfet @  20.1.2010,  12:08 Найти цитируемый пост)
Нормально ли так? 

нет. это уже будет не в потоке.

Добавлено через 3 минуты и 8 секунд
по приведенному вами коду, мне кажется, что можно использовать QWaitCondition, или тупо мьютекс. сложно что-то более точно сказать, так как детали не понятны.

Автор: Elfet 20.1.2010, 12:30
Мне нужно реализовать итерационный процесс решения задачи, который можно с помощью кнопок на форме остановить, возобновить или прекратить вообще.

Автор: SABROG 20.1.2010, 12:46
Я бы посмотрел в сторону QtConcurrent::map()/mapped(), он сам распараллеливает задачу на доступные ядра. Можно поставить на паузу, можно видеть прогресс. А вместо цикла for() должен быть список с задачами или значениями.

Автор: Elfet 20.1.2010, 13:08
SABROG, вообще хотелось бы с помощью потоков. 

Автор: JackYF 20.1.2010, 18:07
Elfet, 
Цитата(Elfet @  20.1.2010,  11:08 Найти цитируемый пост)
Не хочу отдельную тему создавать. 

А надо.

Автор: SABROG 20.1.2010, 19:00
Цитата(Elfet @ 20.1.2010,  13:08)
SABROG, вообще хотелось бы с помощью потоков.

А это и есть отдельные потоки.

Автор: andrew_121 20.1.2010, 19:07
Цитата(Elfet @  20.1.2010,  12:08 Найти цитируемый пост)
Ясно, спасибо!

классно тема начинается, никаких вопросов! smile 


JackYF, переименуй пожалуйста тему: Qt, потоки, запуск/останов.

Автор: Elfet 20.1.2010, 23:10
andrew_121, =))))  smile 

Автор: maxxant 20.1.2010, 23:50
Цитата(Elfet @  20.1.2010,  12:08 Найти цитируемый пост)

У меня на форме есть ещё две кнопки: Пауза и Стоп.
Каким образом можно приостановить выполнение процесса и заново его запустить?

Я сделал так:

Код

void IterationThread::run()
{
    is_runing = true;
    for(; i <= 100; i++)
    {
        emit Progress(i);
        msleep(100);
        if(!is_runing)
        {
            return;
        }
    }
}
void IterationThread::Pause()
{
    is_runing = false;
}




Если пауза - имеется ввиду, приостановить цикл, а потом продолжить с того же места. Тогда наверное как-то так:

Код

void IterationThread::run()
{
    doPause = false;
    doStop   = false;

    for(; i <= 100; i++)
    {
        emit Progress(i);
        msleep(100);
        if(doStop)
        {
            return;
        }
        while(doPause)
        {
           msleep(xxx); // 20 - 50 ms
           if(doStop) return;
        }
    }
}
void IterationThread::Pause(bool on)
{
    doPause = on;
}
void IterationThread::Stop()
{
    doStop = false;
}


ну и конструкция вида:

Код

void IterationThread::run()
{
   ...
        emit Progress(i);
   ...
}


Это обычно диагноз. Поскольку moveToThread() для самого класса потока делать вообщем-то не хорошо. А в коннектах этого сигнала к другим слотам обычно не указывается тип соединения, иногда указывают, но реже. Поэтому, если вдруг в логах (а может раз в месяц) появиться куча сообщений от каких-то сокетов (для X11) при потери связи с иксами или другие интересные глюки, то можно будет добавить в коннекте к слотам тип соединения Qt::QueuedConnection. (но это так догадки, возможно было где-то другое начало темы, начал читать со слов: "ясно, спасибо!"). А ещё лучше сразу сделать дополнительный класс, отдельный от класса потока.


Автор: Elfet 21.1.2010, 14:14
Цитата(maxxant @  21.1.2010,  00:50 Найти цитируемый пост)
Если пауза - имеется ввиду, приостановить цикл, а потом продолжить с того же места. Тогда наверное как-то так:

Так лучше чем заново вызвать метод run()?

Цитата(maxxant @  21.1.2010,  00:50 Найти цитируемый пост)
ну и конструкция вида:

А что в ней такого?

Цитата(maxxant @  21.1.2010,  00:50 Найти цитируемый пост)
А ещё лучше сразу сделать дополнительный класс, отдельный от класса потока.

Что за дополнительный класс? 


Мне нужно создать отдельный поток с итерационным решением и возможностью его приостановить/возобновить или вообще остановить.

Автор: Elfet 21.1.2010, 14:37
И ещё я в документации про Qconcurrent прочитал следующее:
Цитата
the future returned by QtConcurrent::run() cannot be canceled;

Автор: SABROG 22.1.2010, 00:52
Цитата(Elfet @ 21.1.2010,  14:37)
И ещё я в документации про Qconcurrent прочитал следующее:
Цитата
the future returned by QtConcurrent::run() cannot be canceled;

Дык речь о методе run(), который не умеет практически ничего. Не умеет отправлять сигналы о состоянии прогресса, не может быть прерван, не умеет распараллеливать задачи. Я же рекомендовал использовать методы map() или mapped(), которые всё умеют.

Автор: Elfet 22.1.2010, 01:28
Всё же мне не хочется использовать этот QtConcurren.

Какие могут быть проблемы если я буду делать с QThread и событиями для остановки? 

Автор: andrew_121 22.1.2010, 02:48
какие угодно. все зависит от того что будет в цикле, и как оно работает.

Автор: maydjin 25.1.2010, 01:12
Вариант с переменными 
Цитата

doPause = false;
doStop   = false;

может вызвать довольно много проблемм, я бы предложил использовать для ваших целей класс QSemaphore делаеться это примерно так :
Код

// 
class TestThread:public QThread
{
Q_OBJECT
public:
    TestThread():sm(1){}
void run();

void  suspend(){sm.acquire(1);}
void  resume(){sm.release();}

protected:
QSemaphore sm; 
};

//
void TestThread::run()
{
    while(1)
    {

        sm.acquire();
        qDebug()<<"I'M ALIVE!!!"<<sm.available();
        sm.release();

    }

}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)