Schumi |
Отправлено: 01.06.2005, 20:35 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
Я работаю в своей программе с потоком:
1) сперва создаю через CreateThread
2) в функции потока проверяю некоторую переменную, условно: ThreadTerminate. И если она true — выхожу. Ясно, что с учетом алгоритма работы, проверяется она не всегда, а через некоторый промежуток времени (идут некие фоновые расчеты).
Понятно, что возникают трудности, когда закрывается программа, а поток продолжает работать.
На данный момент, как я делаю: устанавливаю ThreadTerminate в true. После это в цикле (условно i=0...10) — проверяю GetExitThread (вроде так называется) ,если еще активна, то делаю паузу в 200 мс и снова проверяю. Если закончилась работа, то CloseHandle.
Я догадываюсь, что есть более оптимальный вариант с прекращением работы процесса . Посоветуйте.
|
|
Asher |
Отправлено: 02.06.2005, 08:58 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
Логически все верно и ничего особо здесь не придумаешь.
Единственно что — так это лучше ограничивать время нахождения внутри твоих вычислений, чтобы за время ожидания завершения поток успел флаг проверить.
Ну и ждать завершения можно не циклом, а WaitForSingleObject(hThread, MyPause);
где MyPause — время которое ты согласен подождать завершения потока. У тебя это 2*100 мс.
Ну и хороший вариант — не грохать потоки просто так, а только при завершении программы. Если приходится пользоваться потоком несколько раз, то по завершении вычисления отправлять его в сон, по
WaitForSingleObject(hEvent, INFINITE);
и когда нужно снова посчитать — будить посылкой SetEvent(hEvent);
Ну и после выставления ThreadTerminate только неплохо бы поток будить.
|
|
Тиграша |
Отправлено: 03.06.2005, 05:31 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 24
|
А мне вот тут помогли
Mark Cashman |
|
Георгий |
Отправлено: 03.06.2005, 10:07 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
QUOTE (Тиграша @ 03/06/2005, 06:31) | А мне вот тут помогли
Mark Cashman |
у нас в "уроках" что-то похожее было, но на русском языке |
|
Schumi |
Отправлено: 03.06.2005, 20:35 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
Тогда хочется поставить вопрос ребром. Кратко суть проблемы: у меня есть некая таблица. Число строк очень велико, для каждой строки нужно вычислять значение (время вычисления — пару секунд). Если сразу считать значения всей таблицы, то уходит время — много ~1 мин.
Как я переделал: в событии OnDraw таблицы делаю так: если для данной строки еще значение не вычислено, то вычисляю, если вычислено, то беру и вывожу. Т.е получается, некоторый расчет на лету. С другой стороны — в фоновом режиме запускаю поток, который аналогично вычисляет значение всех еще не обработанных строк.
Обработка вычисляется посредством вызова функции (Func), условно — она принимает номер строки, и возвращает требуемое значение. Причем в ней проверяется — расчитано значение или нет.
Вы спросите — а зачем мучатся с потоком, если действительно, обрабатывать строки по мере надобности. Отвечу — помимо этого пользователю нужно подсчитывать некоторый критерий. Достоверность результата возможно лишь в случае обработки всех строк. Таким образом у меня постоянно в в Func выводится текущее значение критерия и % обработанных строк.
В принципе работает. Хотя иногда у label и progressbar, которые обновляются в Func меняется цвет . Самое интересное, с таким успехом можно проблем не разгрести, учитывая, что в основной проге по событию OnDraw и в потоке вызывается одна и таже функция.
Ясно, что надо как-то контролировать работу этой функции, чтобы работал одновременно только один.
Я читал, что можно это делать через mutex, семафоры, timer и increment/decrement крученый. Я попробовал через CreateMutex — ReleaseMutex. Но учитываю, что не совсем разобрался (если не сказать больше ).
Объясните, пожалуйста, кто знает, на пальцах, как это сделать. Или если у кого есть уже опыт, какими средствами лучше воспользоваться.
|
|
Schumi |
Отправлено: 11.06.2005, 22:47 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
С этим разобрался. Но теперь другая проблема — я хочу в функции потока показать форму. То есть что-то далется, прогресс идет и в некоторый момент времени надо, чтобы появилась сообщение (реализовываю через форму).Испробовал разные варианты: создавал прямо в функции или уже была создана: при этом форма должна показываться не модально — и через ShowWindow и через Show. Все одно — оно появляется и тут же исчезает. В чем причина?
|
|
Konstantine |
Отправлено: 13.06.2005, 09:29 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
из потока с функциями VCL работать только через Sinhronize()
|
|
Schumi |
Отправлено: 13.06.2005, 14:07 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
Мой опыт показывает, что не обязательно — многое получалось выполнять и из потока: устанавливать свойства, вызывать методы
|
|
Георгий |
Отправлено: 13.06.2005, 15:02 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
QUOTE (Schumi @ 13/06/2005, 15:07) | Мой опыт показывает, что не обязательно — многое получалось выполнять и из потока: устанавливать свойства, вызывать методы |
а вот этого не надо — ошибки из за повторной невходимости в функции гораздо страшнее и разрушительнее даже, чем промахи по памяти.
причём проявляются они гораздо реже, и зачастую с тестовой обвязкой не выявляются, а на объекте у заказчика вылазят.
лучше не надо — нервы дороже. |
|