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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Не убивается поток Qt3.3.8 VC2005  (Прочитано 13677 раз)
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #15 : Декабрь 20, 2010, 17:49 »

Попробовал
Код:
parVF->exit()
Приложение валится, а процесс как ни в чем ни бывало фурычит и дальше Непонимающий
Записан

Как мало времени и как много нужно узнать
sadhu
Гость
« Ответ #16 : Декабрь 20, 2010, 20:24 »

3 Qt остался на работе, но в 4 имееться дополнительная "защита от дурака", дабы получить возможность убивать нити методом terminate надо в любом месте программы вызвать защищённый статический метод
void setTerminationEnabled ( bool enabled = true ).
Если в 3 аналога нет , то завтра если не запамятую гляну , т.к как раз похожую ситуацию мне и предстоит в ближайшем будующем реализовать Улыбающийся
Записан
Fat-Zer
Гость
« Ответ #17 : Декабрь 20, 2010, 20:29 »

нет, в 3-их такой защиты нет... в 4-х даже после вызова этого метода поток постоянно выполняющийся не убивается...
Записан
sadhu
Гость
« Ответ #18 : Декабрь 20, 2010, 21:13 »

В третьих пока могу посмотреть только документацию, кстати возможно стоит просто дождаться когда процесс прерветься ( QThread::wait() ) ибо "The thread may or may not be terminated immediately, depending on the operating system's scheduling policies." .

Что имееться в виду под
в 4-х даже после вызова этого метода поток постоянно выполняющийся не убивается...

Спецом проверил ща и убиваеться в любом случае и при
Код:
...
TestThread::run()
{
while(true){полезная_нагрузка_дабы_не_убило_оптимизацией;}
}
...
и при
Код:
...
TestThread::run()
{
полезная_нагрузка;
exec();
}
...
Записан
Fat-Zer
Гость
« Ответ #19 : Декабрь 20, 2010, 21:42 »

О_о я тоже только сегодня днём пробовал...
Не убивается, мой пример:

Код:
// widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QThread>

class Thread: public QThread
{
public:
Thread()
{
setTerminationEnabled(1);
}

void run()
{
int i;
while(1) i++;
}

};

class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
public slots:
void terminateThread();
private:
Thread *thr;
};

#endif // WIDGET_H


// widget.cpp
#include <QPushButton>
#include "widget.h"

Widget::Widget(QWidget *parent)
:QWidget(parent)
{
QPushButton *btn=new QPushButton(this);
thr = new Thread();
thr->start();
connect(btn,SIGNAL(clicked()),
this,SLOT(terminateThread()));
}

void Widget::terminateThread()
{
thr->terminate();
thr->wait();
}



// main.cpp
#include <QApplication>
#include "widget.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

Widget w;
w.show();
return a.exec();
}

Тоже самое, если setTerminationEnabled(1) ставить где-либо ещё...
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #20 : Декабрь 21, 2010, 10:19 »

Самое неприятное, что метод
Код:
Qt::HANDLE currentThread () 
возвращает код GUI-потока. Непонимающий
Так что и системными средствами не убить зависший поток Злой
Записан

Как мало времени и как много нужно узнать
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #21 : Декабрь 21, 2010, 10:44 »

Пробовал ставить минимальный приоритет...
Не помогает Непонимающий
Как жрал 99%, так стал 96% жрать и все Смеющийся
Записан

Как мало времени и как много нужно узнать
brankovic
Гость
« Ответ #22 : Декабрь 21, 2010, 15:59 »

С qthread не знаю что, но сама постановка нехорошая:

Проблема

1. допустим таки убили вы тред. В результате утечка памяти (в момент postMessage). Кроме того, убивание malloc в середине вызова может привести вообще к падению или завису malloc в другом треде. Зачем вам такая программа?

Варианты решения

2. вставить в calc проверку флага, по которому тред культурно выходит (предлагали уже выше). Пусть написано другим разработчиком, если код доступен, вставьте флаг. Это простой путь.

3. можно запустить calc в отдельном процессе. Не знаю, насколько просто ipc в кьют, но принципиально это возможно. Это долгий путь. Но устойчивость получится выше.
Записан
Waryable
Гость
« Ответ #23 : Декабрь 22, 2010, 09:32 »

Согласен с последним автором. Убиение потока "топором" - это всегда не хорошо. В данном случае полагаться на то, что система разрулит то, что вы не смогли разрулить своим кодом не безопасно. Тем более, что ввести флаг, разрешающий/запрещающий дальнейшую работу, довольно просто.
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #24 : Декабрь 22, 2010, 15:01 »

Нет у меня доступа к исходному коду модуля вычислений...
При его убиении я ничего не теряю
Записан

Как мало времени и как много нужно узнать
brankovic
Гость
« Ответ #25 : Декабрь 22, 2010, 15:38 »

Если доступа действительно нет, то единственный надёжный вариант -- запустить в отдельном процессе. В документации есть некий QProcess, например. На вид то, что нужно.

При его убиении я ничего не теряю

Что значит, "я ничего не теряю"? Вот микрософт нам пишет:

http://msdn.microsoft.com/en-us/library/ms686717%28v=vs.85%29.aspx


суть:

Цитировать
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code. DLLs attached to the thread are not notified that the thread is terminating. The system frees the thread's initial stack.

    Windows Server 2003 and Windows XP/2000:  The target thread's initial stack is not freed, causing a resource leak.

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:

    * If the target thread owns a critical section, the critical section will not be released.
    * If the target thread is allocating memory from the heap, the heap lock will not be released.
    * If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
    * If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

Обратите внимание на замечание про 2003/2000/XP, память будет течь независимо от вашего кода или от реализации calc.

Даже если течь не смущает или платформа другая, всё равно. Не имея кода calc, как вы можете быть уверены, что там не вызывается malloc? Один прерванный malloc, это на 99% либо падение, либо зависание в _любом_ треде! С таким же успехом "оператор" может снимать программу на ctrl-alt-del и запускаться заново.

Итого: причина, по которой QThread::terminate не работает под windows в том, что terminate там вообще не нужен. Но тот же метод вполне безопасно реализован в linux и, возможно, ещё на каких-то платформах, только поэтому он продолжает существовать.
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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