![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как приостановить поток?
volser © (2005-08-23 12:23:00)вот часть кода
В ПОТОКЕ:
while not Terminated do
begin
if not Paused then
begin
try
ExecTick := False;
...
finally
ExecTick := True;
end;
end;
Sleep(10);
end;
В ГЛАВНОМ ПОТОКЕ:
Thread.Paused := True;
while not Thread.ExecTick do
begin
Windows.Beep(500,50);
end;
...
Thread.Paused := False;
Иногда цикл залипает. В чем проблема?
Fay (2005-08-26 14:42:00) [1]2 Alexander Panov © (26.08.05 13:51) [139]
Видимо, имеется некий гипотетический (или даже написанный Slym) класс, являющийся обёрткой для Event, метод Pulse которого вызывает PulseEvent.
Не сказал бы, что испытываю по этому поводу какие-либо эмоции, но рад за Вас 8).
Alexander Panov (2005-08-26 13:51:00) [2]Fay © (26.08.05 13:26) [138]
Но ведь TCriticalSection не умиляет?
А вот Pulse - умиляет.
Fay (2005-08-26 13:26:00) [3]2 Alexander Panov © (26.08.05 11:30) [136]
>> На кой?
Для тех случаев, когда про доп. потоки мы знаем только то, что они, возможно, есть. Правда весь код тогда будет сильно отличаться, но ведь можно "пофантазировать" (© Defunct), что Slym имел ввиду и это...
2 Alexander Panov © (26.08.05 11:31) [137]
Но ведь TCriticalSection не умиляет?
8)
Alexander Panov (2005-08-26 11:31:00) [4]Особенно умиляет Event.Pulse
Alexander Panov (2005-08-26 11:30:00) [5]Slym © (26.08.05 10:56) [134]
Не проще Event создать?
На кой?
Slym (2005-08-26 11:00:00) [6]Удалено модератором
Slym (2005-08-26 10:56:00) [7]Не проще Event создать?
в потоке Event.WaitFor
в основном потоке Event.Pulse
Alexander Panov (2005-08-26 10:16:00) [8]Справедливо. Придется весь список блокировать.
procedure Execute;
var
i: Integer;
begin
while not Terminated do
begin
Lock;
try
for i := 0 to FList.Count-1 do
begin
if Terminated then Exit;
//Работаем со строкой из списка.
end;
finally
Unlock;
end;
Suspend;
end;
end;
Игорь Шевченко (2005-08-26 10:02:00) [9]И эти люди запрещают мне ковырять в носу (с) известный анекдот
Fay (2005-08-26 04:19:00) [10]2 Alexander Panov © (25.08.05 23:19) [130]
Пример довольно приличный.
"Опечатка" только одна : procedureTListProcess.Execute;
Но есть и злобные баги, которые, видимо, происходят от позднего времени и конца трудовой недели 8).
for i := 0 to FList.Count-1 do
begin
Lock;
try
Lock после for - не кошерно. Совершенно не очевидно, что количество не изменится. Тут и модный Clear не спасёт.
if FList.Count=0 then Break;
Обращение вне кр. секции - ахтунг.
Alexander Panov (2005-08-25 23:19:00) [11]volser (25.08.05 22:20) [128]
Вобчем, держи пример.
Возможны опечатки, так как код писал прямо здесь.
TListProcess=class(TThread)
private
FList: TStringList;
FCS: TCriticalSection;
procedure Lock;
procedure Unlock;
protected
procedure Execute; override;
public
constructor Create(List: TStringList);
destructor Destroy; override;
procedure Clear;
procedure Start;
procedure Stop;
end;
implementation
constructor TListProcess.Create(List: TStringList);
begin
inherited Create(True);
FreeOnTerminate := True;
FCS := TCriticalSection.Create;
FList := List;
end;
destructor TListProcess.Destroy;
begin
FCS.Free;
inherited;
end;
procedure TListProcess.Clear;
begin
Lock;
try
FList.Clear;
finally
Unlock;
end;
end;
procedure TListProcess.Lock;
begin
FCS.Enter;
end;
procedure TListProcess.Unlock;
begin
FCS.Leave;
end;
procedure TListProcess.Start;
begin
Resume;
end;
procedure TListProcess.Stop;
begin
Lock;
try
Suspend;
finally
Unlock;
end;
end;
procedure Execute;
var
i: Integer;
begin
while not Terminated do
begin
for i := 0 to FList.Count-1 do
begin
Lock;
try
//Работаем со строкой из списка.
finally
Unlock;
end;
if FList.Count=0 then Break;
end;
Suspend;
end;
end;
Defunct (2005-08-25 22:51:00) [12]volser (25.08.05 22:20) [128]
При проектировании канализации можно, конечно, закладывать гнилую деревянную трубу, а места где течет - затыкать паклей, только все равно дерьмо просочится через время в другом месте.
volser (2005-08-25 22:20:00) [13]
> Галиматья какая-то, причем тут Try?
При том, что если лист очищается то вылетает exception после чего продолжается следующий виток цикла с обновленными данными.
Fay (2005-08-25 21:55:00) [14]2 volser (25.08.05 21:27) [125]
Приведённый [0] код корявый, можете его больше не приводить.
Вам будет лучше объяснить решаемую по-русски.
Defunct (2005-08-25 21:35:00) [15]volser (25.08.05 21:27) [125]
Галиматья какая-то, причем тут Try?
volser (2005-08-25 21:27:00) [16]Я нашел попроще решение, просто поставил try в тело цикла вспомагательного потока :-)
Главное что работает.
Defunct (2005-08-25 20:54:00) [17]> Fay © (25.08.05 19:04) [123]
Прочитайте сабж ;>
ведь речь не шла о том как правильно сделать синхронизацию, речь шла о приостановке потока ;>
> Игорь Шевченко © (25.08.05 18:39) [118]
Хаха, мазохизмъ
Fay (2005-08-25 19:04:00) [18]2 Alexander Panov © (25.08.05 18:51) [121]
>> не приходила в голову простая мысль, что защищаются не данные, а код,
Нет. ТАКАЯ мысль мне в голову не приходила.
Что Вы курите?
Alexander Panov (2005-08-25 18:53:00) [19]Смысла в продолжении дискуссии нет, так как для всех поставленных условий не вижу существенных проблем в реализации...
Alexander Panov (2005-08-25 18:51:00) [20]Кстати, не приходила в голову простая мысль, что защищаются не данные, а код, и что в этот код всегда можно передать все, что угодно, в том числе и экземпляр потока?