Russian Qt Forum

Qt => Общие вопросы => Тема начата: lepsai от Март 07, 2005, 21:46



Название: Остановить поток на скаку
Отправлено: lepsai от Март 07, 2005, 21:46
Вот такой вопрос: как организовать в qt нечто вроде
QThread::pause()
QThread::resume()

с одним условием:

MyThread::run()
{
doWork();
}

doWork(): Все операции в этой функции реализованны в некоторой dll и не имеют никакого отношения к qt и этому потоку.


Название: Остановить поток на скаку
Отправлено: lepsai от Март 07, 2005, 21:56
можно использовать
SuspendThread() и ResumeThread()

Ну а как сделать в qт?


Название: Остановить поток на скаку
Отправлено: Admin от Март 07, 2005, 22:11
под виндой мона попробовать

Qt::HANDLE QThread::currentThread () [static]
This returns the thread handle of the currently executing thread.
Warning: The handle returned by this function is used for internal purposes and should not be used in any application code. On Windows, the returned value is a pseudo handle for the current thread, and it cannot be used for numerical comparison.

получил хандл на поток и используешь виндовые функции
это только под виндой


Название: Остановить поток на скаку
Отправлено: lepsai от Март 07, 2005, 23:42
Вот мать иx...

Тролли додумались - возвращяют в QThread::currentThread() вместо
HANDL'A  GetCurrentThreadID(). А толку то с него...

Когда передаёшь в SuspendThread(), GetLastError() сообщает "invalid handle"


Название: Остановить поток на скаку
Отправлено: Admin от Март 08, 2005, 00:35
остается с тролями поругатся
а вообще может имеет смысл поискать по рассылке
может это чем то оправдано !!


Название: Остановить поток на скаку
Отправлено: lepsai от Март 08, 2005, 01:03
Ну плоxое решение реализовал так:

void MyThread::run()
{
int id = (int)QThread::currentThread();
g_workerHandle = OpenThread(THREAD_ALL_ACCESS, true, id);
}

ну а потом:

SuspendThread(g_workerHandle)
ResumeThread(g_workerHandle)

OpenThread() не было в VC 6.0, пришлось ставить Plattform SDK. Hу вобщем гемморой!


Название: Остановить поток на скаку
Отправлено: Sergeich от Март 09, 2005, 15:46
Цитировать

Ну плоxое решение реализовал так:

Лучшего решения под Qt нет. Под линухом, насколько я знаю, вообще нет возможности приостанавливать/возобновлять потоки, так что ждать появления таких методов в Qt не стоит.


Название: Остановить поток на скаку
Отправлено: Denwer от Апрель 01, 2005, 15:26
Решение троллей разумеется оправдано, я конечно тоже не знаю как там обстоят дела в линуксе, но точно знаю что приостанавливать/запускать поток в томже виндовсе нужно крайне осторожно, я вижу пользу в этиъ махинация только в одной ситуации, когда нужно создать приостановленный поток, а потом после каких то действий его запустить, но если поток начал работать уж извольте его не останавливать таким жестоким способом, из этого ничего хорошего не выйдет.


Название: Остановить поток на скаку
Отправлено: lepsai от Апрель 01, 2005, 15:48
ну и каковы же Ваши предложения, сударь, для решения следующей задачи:

у Вас есть некая процедура, которая проводит очень обьёмные вычисления.
Доступа к исxодному коду этой процедуры у Вас нет. В Вашей програме Вам необxодимо временно остановить вычислительный процесс,а потом возобновить его. Как бы Вы это сделали?


Название: Остановить поток на скаку
Отправлено: Denwer от Апрель 01, 2005, 16:14
Для ответа надо бы знать саму задачу. И ответ тоже неплохо узнать, зачем ее вообще останавливать.
ЗЫ: Кстати уж если у вас нет доступа к ее коду так темболее не нужно ее сотанавливать.


Название: Остановить поток на скаку
Отправлено: lepsai от Апрель 01, 2005, 17:44
описанная процедура проводит диффузионную фильтрацию изображения. Поскольку этот процесс является итеративным, пользователь желает видеть промежуточные результаты. Чтобы ему предоставить возможность, эти результаты рассмотреть и проанализировать, необxодимо приостановить процедуру...


Название: Остановить поток на скаку
Отправлено: Sergeich от Апрель 01, 2005, 20:48
По поводу приостановления/возобновления потоков под виндой:
Пользуй SupsendThread/ResumeThread, я останавливал потоки при записи в сокет и при записи в в файл, а потом возобновлял, никаких косяков при этом замечено не было, причем все тестировалось довольно жестко. По поводу OpenThread под VS6 : говорят, что можно скачать обновления WinSDK ( ессно платно, как и все у Microsoft ), к-ые позволяют это делать.


Название: Остановить поток на скаку
Отправлено: Denwer от Апрель 04, 2005, 11:07
Попорядку:
1) причем все тестировалось довольно жестко
Больше чем уверен что тестирования на многопроцессорной машине не было. Да и кстати оверлаппед не использовал поди в своем коде.
2) По поводу OpenThread под VS6
OpenThread Requires: Windows XP, Windows 2000 Professional, or Windows Me.
Зачем ее использовать если половина платформ не имеют ее поддержки.
GetCurrentThread Requires: Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95
Вот тут все намного лучше. Как я понял автор этого вопроса имеет возможность вызвать из нужного потока эту функцию.

Вопросы по существу: каким образом можно получить промежуточный результат?

ЗЫ: Вопрос на уточнение: что позволяют делать SDK?
ЗЫЫ: Если уж очень хочется вызвать функцию, для которой нет заголовочного файла, то это намного быстрее можно сделать напрямую вызвав функцию импорта из нужной DLL, нежели качать SDK.


Название: Остановить поток на скаку
Отправлено: lepsai от Апрель 04, 2005, 13:42
Цитировать
GetCurrentThread Requires: Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95
Вот тут все намного лучше. Как я понял автор этого вопроса имеет возможность вызвать из нужного потока эту функцию.

Это не совсем так: я могу вызвать функцию GetCurrentThreadId(), которая имеет смысл только вместе с OpenThread().

Цитировать
Вопросы по существу: каким образом можно получить промежуточный результат?



примерно так:  

typedef void (*update_image_function)(Image & );
doOperation(update_image_function func);


Qt:

void updateImage(Image & im)
{
// show and update image
}

void onStartOperation()
{
doOperation(updateImage);
}


Название: Остановить поток на скаку
Отправлено: Denwer от Апрель 05, 2005, 09:53
Цитировать
Это не совсем так: я могу вызвать функцию GetCurrentThreadId(), которая имеет смысл только вместе с OpenThread().


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

Дальше. А зачем приостанавливать поток после получения данных, ну понизи его приоритет до самого маленького и пущай дальше работает, и не будет  тратить время на простой, ну а если результат уже едовлетворяет, ну и хорошо.
Кстати вот например та ситуация при которой будет дедлок если остановать поток. Предположим поток захотел освободить динамическую память, и так как приложение у нас многопоточное, то CRT тоже многопоточная, а это значит что таже операция malloc(да и многие другие) лочатся с помощью критической секции, и вот после того как она залочила секцию мы берем и останавливаем этот поток, а потом в основном потоке опять пытаемся вызвать malloc, и тут то дедлок обеспечен. И кто скажет что он может на 100 процентов сказать что когда он остановит поток,что у него не останется не отного залоченного ресурса. Такие совпадения очень трудно отлаживать из-за очень друдного воспроизведения данной ситуации.


Название: Остановить поток на скаку
Отправлено: lepsai от Апрель 05, 2005, 13:53
Хм... Интересный тезис... надо проверить будет. В принципе у меня всё работает и никакиx проблем нет, но кто знает...