![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как главному потоку узнать что другой уже закончил работу. [D7, Win95/98, Win2k, WinXP]
Kolan © (2005-07-05 14:31:00)Здравствуйте:
1. Есть структура.
MeasurmentDataRec
2. Есть тип - указатель на такую структуру.MeasurmentDataRec: PMeasurmentData
3. Есть поток у которого поле - это указатель на структуру
TMeasurmentThread = class(TThread)
private
protected
public
FMeasurmentDataRec: PMeasurmentData;
constructor Create(CreateSuspended: Boolean;
MeasurmentDataRec: PMeasurmentData);
4. При создании потока в его поле передается указатель на структуру.
5. Поток работает с переданной структурой(заполняет её).
6. После того как поток закончил работу надо показать результат пользователю для этого используется процедура
ShowMeasurmentResults(MeasurmentDataRec: PMeasurmentData)
Вопрос:
1. Как запустьть процедуруShowMeasurmentResultsпо окончании работы потока.
2. Как убить поток по окончании его работы.
Fay (2005-07-05 15:30:00) [21]Доп. потоки должны ломиться в CS, а основной нет. Он волшебный?
Kolan (2005-07-05 15:29:00) [22]
> конец концу - рознь.
> что ты подразумеваешь под "концом" ?
Ну все он отработал и мне не нужен до следующего раза. Если я снова вызову Create. То наверно потеряю ссылку на пред. попоток?Сейчас сделал FreeOnTerminate. И в конце Execute потока Thread.Terminate. Нормально?
> Есть. Только это не метод, а свойство. И свойству достаточно
> присвоить ссылку на метод.
А c этим никак не разбирусь. Можно пример.
Вот есть процедура
TMeasurmentThread = class(TThread)
private
protected
public
{...}
procedure DoTerminate;
end;
Как её выполнить по событию Terminate.
Digitman (2005-07-05 15:25:00) [23]
> Fay © (05.07.05 15:24) [17]
> А это правильно?
а почему нет ?
Fay (2005-07-05 15:24:00) [24]2 Digitman © (05.07.05 15:21) [15]
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod
А это правильно?
Digitman (2005-07-05 15:24:00) [25]
> begin...end © (05.07.05 15:21) [14]
т.е. наивно полагая, что synchronize синхронизирует вып-е указ.метода с осн.трэдом процесса обязательно и безусловно, можно в ряде ситуаций и вляпаться
Digitman (2005-07-05 15:21:00) [26]
> содержит значение идентификатора трэда
читать как содержит значение идентификатора неосновноготрэда
begin...end (2005-07-05 15:21:00) [27]> Fay © (05.07.05 15:11) [11]
Не в любом.
> Digitman © (05.07.05 15:17) [12]
ОК, ясно.
Digitman (2005-07-05 15:19:00) [28]цитата (Д7):
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
var
SyncProc: TSyncProc;
begin
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod
...
т.е. при выполнении условия GetCurrentThreadID = MainThreadID метод FMethod тут же будет синхронно выполнен в контексте того трэда, который вызвал Synchronize
Digitman (2005-07-05 15:17:00) [29]
> В каком случае не в основном?
в случае когда MainThreadID содержит значение идентификатора трэда, инициализировавшего экз-р модуля System
Fay (2005-07-05 15:11:00) [30]begin...end © (05.07.05 15:10) [10]
В любом. Крит. секция не меняет коду поток.
begin...end (2005-07-05 15:10:00) [31]> Digitman © (05.07.05 15:03) [8]
В каком случае не в основном?
Fay (2005-07-05 15:07:00) [32]2 begin...end © (05.07.05 15:02) [6]
2 Digitman © (05.07.05 15:03) [8]
Точно. Нашёл
procedure TThread.DoTerminate;
begin
if Assigned(FOnTerminate) then
Synchronize(CallOnTerminate);
end;
Это, конечно, не "в основном", но уже кое-что.
Digitman (2005-07-05 15:03:00) [33]
> В основном, а что?
не обязательно, но как правило
Digitman (2005-07-05 15:02:00) [34]можно еще сделать так (без использования OnTerminate):
//стартуем доп.трэд
MyThread := TMyThread.Create(параметры);
try
//пока приложение работает
while not Application.Terminated do
//ждем либо завершения потока либо любого сообщения в очереди сообщений окнам тек.трэда
case MsgWaitForMultipleObjects(1, MyThread.Handle, False, INFINITE, QS_ALLINPUT) of
WAIT_OBJECT_0: break; //доп.трэд завершил свою работу
WAIT_OBJECT_0 + 1: Application.ProcessMessages; //обработаем сообщения окнам
finally
MyThread.Free;
end;
begin...end (2005-07-05 15:02:00) [35]> Fay © (05.07.05 15:00) [5]
В основном, а что?
Fay (2005-07-05 15:00:00) [36]begin...end © (05.07.05 14:52) [4]
А в каком потоке выполняется OnTerminate ?
begin...end (2005-07-05 14:52:00) [37]> Kolan © (05.07.05 14:47) [2]
> ShowMeasurmentResults находится в модуле главной
> формы. И модуль где поток ничего не знает о её
> сушествование.
> Может надо прередать её указатель?
Можно и так.
А может, просто в список uses модуля потока добавить модуль формы?
Есть и ещё вариант: по окончании работы потока посылать форме сообщение, а в обработчике этого сообщения формы запускать ShowMeasurmentResults. Но для этого потоку нужно будет знать, КУДА посылать сообщение, а значит, при его создании нужно будет передавать хэндл окна формы.
> MyThread.OnTerminate есть ?
Есть. Только это не метод, а свойство. И свойству достаточно присвоить ссылку на метод.
Digitman (2005-07-05 14:52:00) [38]
> MyThread.Free
> прямо в конце? Прававильно?
конец концу - рознь.
что ты подразумеваешь под "концом" ?
> Что - то не получилось переопредилить OnTerminate
это событие, а не метод
Kolan (2005-07-05 14:47:00) [39]Забыл сказать
ShowMeasurmentResultsнаходится в модуле главной формы. И модуль где поток ничего не знает о её сушествование.
Может надо прередать её указатель?
MyThread.Free
прямо в конце? Прававильно?
Что - то не получилось переопредилить OnTerminate
procedure OnTerminate; override;
Ошибка
Method 'OnTerminate' not found in base class
MyThread.OnTerminate есть ?
Digitman (2005-07-05 14:34:00) [40]
> 1. Как запустьть процедуру ShowMeasurmentResults по окончании
> работы потока
например, вызвать ее в обработчике события TThread.OnTerminate
> 2. Как убить поток по окончании его работы
MyThread.Free