![]() |
| ||
|
|
Новости |
Поиск |
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;
Иногда цикл залипает. В чем проблема?
Reindeer Moss Eater (2005-08-23 14:05:00) [121]А Вы можете продемострировать надёжную защиту данных с помощью Suspend? Интересно взглянуть, т.к. я плохо себе это представляю.
Главный поток вызывает suspend.
Убеждается в том, что вторичный поток спит.
Изменяет список.
Выставляет нужное свойство у вторичного потока.
Вторичный поток в своем коде прежде чем использовать элемент списка по индексу проверяет значение свойства-флага.
Хотя я бы конечно так не стал делать.
Fay (2005-08-23 13:57:00) [122]2 Alexander Panov © (23.08.05 13:42) [17]
>> Без проблем. Но речь не об этом.
Не хотелось бы показаться занудой, но мне кажется, что были некоторые причины, по которым Вы применили именно кр. секции, а не прекрасный во всех отношениях Suspend...
Alexander Panov (2005-08-23 13:46:00) [123]Забыл в описание класса потока добавить поле для доступа к списку:
TThr=class(TThread)
private
FCS: TCriticalSection;
FList: TStringList;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
procedure Lock;
procedure Unlock;
procedure Terminate;
procedure Start;
procedure ClearList;
property List: TStringList read FList;
end;
Работать со списком можно так:
Thr.Lock;
try
if Thr.List.Count>0 then Memo1.Lines.Add(Thr.List[0]);
finally
Trh.Unlock;
end;
Alexander Panov (2005-08-23 13:42:00) [124]Fay © (23.08.05 13:09) [14]
А Вы можете продемострировать надёжную защиту данных с помощью Suspend?
Без проблем. Но речь не об этом.
volser (23.08.05 12:59) [8]
Пример потока для твоего случая:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,SyncObjs, StdCtrls;
type
TThr=class(TThread)
private
FCS: TCriticalSection;
FList: TStringList;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
procedure Lock;
procedure Unlock;
procedure Terminate;
procedure Start;
procedure ClearList;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Thr: TThr;
List: TStringList;
implementation
{$R *.dfm}
{ TThr }
procedure TThr.ClearList;
begin
Lock;
try
FList.Clear;
finally
Unlock;
end;
end;
constructor TThr.Create;
begin
inherited CReate(True);
FList := TStringList.Create;
FreeOnTerminate := True;
FCS := TCriticalSection.Create;
Resume;
end;
destructor TThr.Destroy;
begin
FCS.Free;
inherited;
end;
procedure TThr.Execute;
var
i: Integer;
begin
while not Terminated do
begin
if Terminated then Exit;
Lock;
try
{Здесь работаем со списком FList, например:}
for i := 0 to 500 do
begin
FList.Add(IntToStr(FList.Count));
Sleep(10);
end;
finally
Unlock;
end;
Suspend;
end;
end;
procedure TThr.Lock;
begin
FCS.Enter;
end;
procedure TThr.Start;
begin
Resume;
end;
procedure TThr.Terminate;
begin
Resume;
inherited;
end;
procedure TThr.Unlock;
begin
FCS.Leave;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Thr := TThr.Create;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Assigned(Thr) then Exit;
Memo1.Lines.Add('Пытаюсь очистить список...');
Thr.ClearList;
Memo1.Lines[Memo1.Lines.Count-1] := Memo1.Lines[Memo1.Lines.Count-1] + 'Ok';
Thr.Start;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Thr.Terminate;
Thr := nil;
end;
end.
Alexander Panov (2005-08-23 13:34:00) [125]volser (23.08.05 13:20) [15]
Погоди минутку, сейчас пример дорисую.
volser (2005-08-23 13:20:00) [126]А почему тот метод, который я описал в первом посте не катит?
На правильное применения Suspend с интересом посмотрю.
Fay (2005-08-23 13:09:00) [127]2 Reindeer Moss Eater © (23.08.05 13:05) [13]
А Вы можете продемострировать надёжную защиту данных с помощью Suspend? Интересно взглянуть, т.к. я плохо себе это представляю.
Reindeer Moss Eater (2005-08-23 13:05:00) [128]>Fay
Не подойтет вообще ничего, если не уметь организовать взаимодействие потоков.
Fay (2005-08-23 13:04:00) [129]2 Reindeer Moss Eater © (23.08.05 13:02) [11]
Suspend ВАЩЕ не подходит!
Это для крит. секций (и т.п.)
Reindeer Moss Eater (2005-08-23 13:02:00) [130]>Вот я и говорю что suspend не подходит.
Не подходит ТВОЙ способ применения suspend, а не сам suspend.
Reindeer Moss Eater (2005-08-23 13:01:00) [131]Критические секции здесь сами по себе тоже могут не спасти.
Весь цикл должен быть внутри крит. секции.
И если поток туда успел войти, а главный поток усыпил вторичный, то освободить секцию некому.
Тот, кто её занял спит.
Fay (2005-08-23 13:00:00) [132]Щаз кто-нибудь напишет. Я не умею кратко излагать.
volser (2005-08-23 12:59:00) [133]
> Reindeer Moss Eater © (23.08.05 12:57) [6]
Вот я и говорю что suspend не подходит.
volser (2005-08-23 12:58:00) [134]
> Критические секции тебе в руки
А по подробней
Reindeer Moss Eater (2005-08-23 12:57:00) [135]Все верно, поток мог вычислить очередной индекс списка, после чего ты ему делаешь suspend.
Затем список чистится.
Затем resume.
И продолжение выполнение потока.
Причем он понятия не имеет о том, что индекс уже вне границ.
Fay (2005-08-23 12:56:00) [136]volser (23.08.05 12:49) [4]
Критические секции тебе в руки
volser (2005-08-23 12:49:00) [137]
> Ты лучше опиши, чего ты хочешь добиться, тогда можно будет
> предложить метод решения.
Я в потоке работаю со списком (прохожу по циклу от 0 до каунт - 1), но в главном потоке мне нужно этот список очистить. Если не останавливать поток, то естественно иногда выводит, что индекс вышел за пределы допустимых значений. Вот я и хочу приостановить поток таки способом, что бы он дошел свой виток цикла и остановился.
Пробовал Suspend не подходит. Такое ощущение что он останавливается посреди витка цикла, а потом дальше продолжает, но он продолает работать с теми итемами которых нет (так как пределы цыкла вычислются только раз). Вот такая вот трабла.
Alexander Panov (2005-08-23 12:40:00) [138]Для приостановки потока у него есть метод Suspend.
Ты лучше опиши, чего ты хочешь добиться, тогда можно будет предложить метод решения.
volser (2005-08-23 12:35:00) [139]2 Fay
тот, который с бипом.
Fay (2005-08-23 12:32:00) [140]2 volser (23.08.05 12:23)
>> Иногда цикл залипает
Который? Их тут два, вАщЕ-то.