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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Остановить поток на скаку  (Прочитано 18405 раз)
lepsai
Гость
« : Март 07, 2005, 21:46 »

Вот такой вопрос: как организовать в qt нечто вроде
QThread::pause()
QThread::resume()

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

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

doWork(): Все операции в этой функции реализованны в некоторой dll и не имеют никакого отношения к qt и этому потоку.
Записан
lepsai
Гость
« Ответ #1 : Март 07, 2005, 21:56 »

можно использовать
SuspendThread() и ResumeThread()

Ну а как сделать в qт?
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #2 : Март 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
Гость
« Ответ #3 : Март 07, 2005, 23:42 »

Вот мать иx...

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

Когда передаёшь в SuspendThread(), GetLastError() сообщает "invalid handle"
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #4 : Март 08, 2005, 00:35 »

остается с тролями поругатся
а вообще может имеет смысл поискать по рассылке
может это чем то оправдано !!
Записан
lepsai
Гость
« Ответ #5 : Март 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
Гость
« Ответ #6 : Март 09, 2005, 15:46 »

Цитировать

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

Лучшего решения под Qt нет. Под линухом, насколько я знаю, вообще нет возможности приостанавливать/возобновлять потоки, так что ждать появления таких методов в Qt не стоит.
Записан
Denwer
Гость
« Ответ #7 : Апрель 01, 2005, 15:26 »

Решение троллей разумеется оправдано, я конечно тоже не знаю как там обстоят дела в линуксе, но точно знаю что приостанавливать/запускать поток в томже виндовсе нужно крайне осторожно, я вижу пользу в этиъ махинация только в одной ситуации, когда нужно создать приостановленный поток, а потом после каких то действий его запустить, но если поток начал работать уж извольте его не останавливать таким жестоким способом, из этого ничего хорошего не выйдет.
Записан
lepsai
Гость
« Ответ #8 : Апрель 01, 2005, 15:48 »

ну и каковы же Ваши предложения, сударь, для решения следующей задачи:

у Вас есть некая процедура, которая проводит очень обьёмные вычисления.
Доступа к исxодному коду этой процедуры у Вас нет. В Вашей програме Вам необxодимо временно остановить вычислительный процесс,а потом возобновить его. Как бы Вы это сделали?
Записан
Denwer
Гость
« Ответ #9 : Апрель 01, 2005, 16:14 »

Для ответа надо бы знать саму задачу. И ответ тоже неплохо узнать, зачем ее вообще останавливать.
ЗЫ: Кстати уж если у вас нет доступа к ее коду так темболее не нужно ее сотанавливать.
Записан
lepsai
Гость
« Ответ #10 : Апрель 01, 2005, 17:44 »

описанная процедура проводит диффузионную фильтрацию изображения. Поскольку этот процесс является итеративным, пользователь желает видеть промежуточные результаты. Чтобы ему предоставить возможность, эти результаты рассмотреть и проанализировать, необxодимо приостановить процедуру...
Записан
Sergeich
Гость
« Ответ #11 : Апрель 01, 2005, 20:48 »

По поводу приостановления/возобновления потоков под виндой:
Пользуй SupsendThread/ResumeThread, я останавливал потоки при записи в сокет и при записи в в файл, а потом возобновлял, никаких косяков при этом замечено не было, причем все тестировалось довольно жестко. По поводу OpenThread под VS6 : говорят, что можно скачать обновления WinSDK ( ессно платно, как и все у Microsoft ), к-ые позволяют это делать.
Записан
Denwer
Гость
« Ответ #12 : Апрель 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
Гость
« Ответ #13 : Апрель 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
Гость
« Ответ #14 : Апрель 05, 2005, 09:53 »

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


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

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


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