Название: Остановить поток на скаку Отправлено: 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 проблем нет, но кто знает...
|