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

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

Как приостановить поток?


Страницы:   1 2 3 4 5 6 7

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)
>> Иногда цикл залипает
Который? Их тут два, вАщЕ-то.


Страницы:   1 2 3 4 5 6 7

Наверх

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