Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TThread [D6, Win2k]


Страницы:   1 2

Alibaba ©   (2003-08-20 18:39:00) 

Народ, помогите, не могу перезапустить поток.

1 Шаг.
constructor TM1Depend.Create;
begin
...
FreeOnTerminate:=False; //По окончанию не разрушается
inherited Create(True); //Создаем поток c ожиданием. Запуск: Resume

end;

2. Шаг
M1Depend.Resume;

3. Шаг
Обрабатываю результат

4. Шаг
M1Depend.Resume; НЕ РАБОТАЕТ!!!


Alibaba   (2003-10-05 00:30:00) [1]

>Verg © (04.10.03 14:05) [27]

Тоесть, вы считаете, что это правильно?


Verg   (2003-10-04 14:05:00) [2]

Ну и славненько...


Alibaba   (2003-10-04 13:56:00) [3]

>Verg © (04.10.03 08:46) [25]

Все именно так и делается. :)

procedure TDepMain.Execute;
begin
while not Terminated do
begin
.............................
Чего-то делаем
.............................
PostMessage(frmMain.Handle,WM_DepMainMes,0,0);
Suspend;
end;
end;


Verg   (2003-10-04 08:46:00) [4]


> 5. Шаг
> // ждем очер.результата , факт их наличия - опять же Suspended
> = True
> Обрабатываю результат


Так вот как же это "ждем"?

while not t.suspended do sleep(50); - так чтоль?
Или по таймеру проверять?

Я бы сделал так:
После завершения операции поток отправляет (postmessage) сообщение ГКП или его окну о завершении своей работы, и только после этого либо suspend, либо встает на ожидание сообщения типа "фас".


> А M1Depend.Resume - делается из главнойпрограммы


Не суть важно, главная или управляющая.


Alibaba   (2003-10-03 17:58:00) [5]

Не понятно откуда взялся термин упраляющий....

А M1Depend.Resume - делается из главной программы


Verg   (2003-10-03 17:45:00) [6]


> Suspend; // очередное дело сделано - можно чуток поспать,
> пока не разбудят извне


А как упраляющий поток будет "ждать" suspended?


Alibaba   (2003-10-03 17:31:00) [7]

И так, чем отличаются два варианта запуска потоков:

Вариант №1 (Digitman © (21.08.03 10:40) [4])
procedure TM1Depend.Execute;
begin
while not Terminated do
begin
// здесь - вычисления и формирование результата
Suspend; // очередное дело сделано - можно чуток поспать, пока не разбудят извне
end;
end;

Вариант №2 (Digitman © (03.09.03 08:18) [13])
procedure TM1Depend.Execute;
begin
while not Terminated and GetMessage(...) do
begin
...
end;
end;

-Первый проще в реализации, но занимает ресурсы
-Второй сложнее, но во время ожидания не занимает ресурсы

Если так, то лучше, получается, второй?


Digitman   (2003-09-05 17:29:00) [8]


> AndreyAs


см. Polevi © (04.09.03 18:50) [20]

+ пока поток "спит" и не требует квантов проц.времени, он тем не менее будет "разбужен" системой в любой момент времени, при том не без явной пользы : ты посылаешь потоку (или одному из окон, возможно ранее потоком созданных) сообщение с какой-либо командой, и он тут же бросается ее выполнять


Polevi   (2003-09-04 18:50:00) [9]

>AndreyAs (04.09.03 18:28) [19]
не работает а жрет ресурсы, ибо GetMessage "усыпляет" поток


AndreyAs   (2003-09-04 18:28:00) [10]

> Digitman ©

спасибо за ответ

а все-таки, если вернуться сюда:
while not Terminated and GetMessage(...) do

зачем посылать потоку сообщение? Могу я просто установить глобальную переменную, которую читает данный поток?

while not Terminated and FActive do

вроде работает


Digitman   (2003-09-03 16:37:00) [11]


> AndreyAs


> Причем остановить ее надо мгновенно, не дорабатывая текущую
> итерацию до конца.


так в любом случае не получится.
даже если ты экстренно (принудительно) терминитуешь целевой тред вызовом TerminateThread() из другого треда, системе понадобится какое-то (пусть даже незначительное в рамках тек.процесса) время для снятия целевого треда с исполнения и освобождения конторолируемых системой ресурсов, ассоциированных с тредом ходе его создания и старта.

Я думаю, что нет ничего страшного собственно в выполнении какой-то части тек.итерации (в момент поступления сигнала на завершение). Другой вопрос, что в ходе этой итерации могут быть обращения к какому-то ресурсу, совместно используемому несколькими тредами, который в этот момент уже становится недоступным из-за принятия такого решения одним из тредов (подающим сигнал другим тредам). Необходимо предусмотреть какой-то общий для всех тредов объект синхронизации доступа к ресурсу, например, event. Основной тред создает его, дополнительные треды имеют право устанавливать его в сигн.состояние (если какой-то из них командует тем самым другим тредам на "закругление"). Перед тем как выполнить любой из крит.участков итерации, тред, заинтересованный в получении от других тредов такой команды на "закругление" вызывает WaitForSingleObject() с каким-то определенным параметром таймаута ожидания. Если в период этого таймаута event не просигналил (будучи установленный неким тредом в сигн.состояние), можно продолжать выполнение итерации, иначе - идти по и ной (предусмотренной тобой) ветке алгоритма


AndreyAs   (2003-09-03 13:36:00) [12]

> jack128 ©
> Digitman ©

Понял, сорри...
А не подскажете ли, как лучше поступить в моей задаче?
А именно:
Есть n потоков. Каждый из них выпоняет свою задачу, которую заканчивает с окончанием работы всего приложения.
Но в определенной точке работы какой-либо из потоков может создать ситуацию тиипа GlobalStop, то есть - у него сработало некоторое условие, в результае чего он должен сообщить всем остальным потокам "остановить работу и начать сначала".
Причем остановить ее надо мгновенно, не дорабатывая текущую итерацию до конца.

Сейчас я просто прибиваю все потоки и создаю их заново.
Но такой подход не устраивает. Как лучше поступить?


Digitman   (2003-09-03 13:13:00) [13]


> AndreyAs


условие завершения цикла наступит, когда поток примет сообщение WM_QUIT (GetMessage вернет False, во всех прочих случаях вернет True)


> jack128



> прикольное ришение


еще "прикольнее" решение с циклическим вызовом MsgWaitForMultipleObjects() .. в этом случае поток способен ждать и реагировать как на сообщения, ему (и его окнам) адресованные, так и на сигналы самых разнообразных штатных ОС-объектов синхронизации - мьютексы, семафоры, ивенты, процессы и т.д. и т.п.


jack128   (2003-09-03 13:01:00) [14]


> AndreyAs (03.09.03 10:26) [14]

GetMessage - ждет пока не придет сообщение и вернет false только когда в очереди wm_quit. Так что поток завершится либо по Terminate, либо если послать wm_quit.

А вообще прикольное ришение, мне очень понравилось...


AndreyAs   (2003-09-03 10:26:00) [15]

> Digitman ©

так в последнем примере поток, обработав сообщение, просто завершится, а не остановится?


Digitman   (2003-09-03 08:18:00) [16]


> Alibaba


или послпть потоку сообщение с пом. PostThreadMessage()

procedure TM1Depend.Execute;
begin
while not Terminated and GetMessage(...) do
begin
...
end;
end;


Alibaba   (2003-09-02 18:49:00) [17]

>Polevi © (02.09.03 18:04) [10]

Интерестный вариант.
Надо попробовать.


Polevi   (2003-09-02 18:06:00) [18]

PS
ивент с автосбросом в данном примере
SomeEvent:=CreateEvent(nil,false,false,nil)


Polevi   (2003-09-02 18:04:00) [19]

>Alibaba © (02.09.03 17:45) [9]
усыплять поток надо не Suspend"ом а с помощью Synchronization Functions - WaitForSingleObject к примеру

procedure TM1Depend.Execute;
begin
while not Terminated do
begin
WaitForSingleObject(SomeEvent,INFINTE);
end;
end;

4. Шаг
// передаем другие параметры для очередных вычислений в объект-поток

SetEvent(SomeEvent); // разбудим поток - нехай считает снова


Alibaba   (2003-09-02 17:45:00) [20]

>Digitman © (01.09.03 15:45) [7]

???

А какой же правильный????


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо