Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.09.18;
Скачать: [xml.tar.bz2];

Вниз

Как приостановить поток?   Найти похожие ветки 

 
volser   (2005-08-23 12:23) [0]

вот часть кода

В ПОТОКЕ:
 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-23 12:32) [1]

2 volser   (23.08.05 12:23)
>> Иногда цикл залипает
Который? Их тут два, вАщЕ-то.


 
volser   (2005-08-23 12:35) [2]

2 Fay
тот, который с бипом.


 
Alexander Panov ©   (2005-08-23 12:40) [3]

Для приостановки потока у него есть метод Suspend.

Ты лучше опиши, чего ты хочешь добиться, тогда можно будет предложить метод решения.


 
volser   (2005-08-23 12:49) [4]


> Ты лучше опиши, чего ты хочешь добиться, тогда можно будет
> предложить метод решения.

Я в потоке работаю со списком (прохожу по циклу от 0  до каунт - 1), но в главном потоке мне нужно этот список очистить. Если не останавливать поток, то естественно иногда выводит, что индекс вышел за пределы допустимых значений. Вот я и хочу приостановить поток таки способом, что бы он дошел свой виток цикла и остановился.
Пробовал Suspend не подходит. Такое ощущение что он останавливается посреди витка цикла, а потом дальше продолжает, но он продолает работать с теми итемами которых нет (так как пределы цыкла вычислются только раз). Вот такая вот трабла.


 
Fay ©   (2005-08-23 12:56) [5]

volser   (23.08.05 12:49) [4]
Критические секции тебе в руки


 
Reindeer Moss Eater ©   (2005-08-23 12:57) [6]

Все верно, поток мог вычислить очередной индекс списка, после чего ты ему делаешь suspend.
Затем список чистится.
Затем resume.
И продолжение выполнение потока.
Причем он понятия не имеет о том, что индекс уже вне границ.


 
volser   (2005-08-23 12:58) [7]


> Критические секции тебе в руки

А по подробней


 
volser   (2005-08-23 12:59) [8]


> Reindeer Moss Eater ©   (23.08.05 12:57) [6]

Вот я и говорю что suspend не подходит.


 
Fay ©   (2005-08-23 13:00) [9]

Щаз кто-нибудь напишет. Я не умею кратко излагать.


 
Reindeer Moss Eater ©   (2005-08-23 13:01) [10]

Критические секции здесь сами по себе тоже могут не спасти.
Весь цикл должен быть внутри крит. секции.
И если поток туда успел войти, а главный поток усыпил вторичный, то освободить секцию некому.
Тот, кто её занял спит.


 
Reindeer Moss Eater ©   (2005-08-23 13:02) [11]

>Вот я и говорю что suspend не подходит.

Не подходит ТВОЙ способ применения suspend, а не сам suspend.


 
Fay ©   (2005-08-23 13:04) [12]

2 Reindeer Moss Eater ©   (23.08.05 13:02) [11]
Suspend ВАЩЕ не подходит!
Это для крит. секций (и т.п.)


 
Reindeer Moss Eater ©   (2005-08-23 13:05) [13]

>Fay
Не подойтет вообще ничего, если не уметь организовать взаимодействие потоков.


 
Fay ©   (2005-08-23 13:09) [14]

2 Reindeer Moss Eater ©   (23.08.05 13:05) [13]
А Вы можете продемострировать надёжную защиту данных с помощью Suspend? Интересно взглянуть, т.к. я плохо себе это представляю.


 
volser   (2005-08-23 13:20) [15]

А почему тот метод, который я описал в первом посте не катит?
На правильное применения Suspend  с интересом посмотрю.


 
Alexander Panov ©   (2005-08-23 13:34) [16]

volser   (23.08.05 13:20) [15]
Погоди минутку, сейчас пример дорисую.


 
Alexander Panov ©   (2005-08-23 13:42) [17]

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:46) [18]

Забыл в описание класса потока добавить поле для доступа к списку:

 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;


 
Fay ©   (2005-08-23 13:57) [19]

2 Alexander Panov ©   (23.08.05 13:42) [17]
>> Без проблем. Но речь не об этом.
Не хотелось бы показаться занудой, но мне кажется, что были некоторые причины, по которым Вы применили именно кр. секции, а не прекрасный во всех отношениях Suspend...


 
Reindeer Moss Eater ©   (2005-08-23 14:05) [20]

А Вы можете продемострировать надёжную защиту данных с помощью Suspend? Интересно взглянуть, т.к. я плохо себе это представляю.

Главный поток вызывает suspend.
Убеждается в том, что вторичный поток спит.
Изменяет список.
Выставляет нужное свойство у вторичного потока.
Вторичный поток в своем коде прежде чем использовать элемент списка по индексу проверяет значение свойства-флага.

Хотя я бы конечно так не стал делать.


 
Fay ©   (2005-08-23 14:11) [21]

2 Reindeer Moss Eater ©   (23.08.05 14:05) [20]
Потоки имею "привычку" засыпать в самых разных местах, поэтому часть
>> Вторичный поток в своем коде прежде чем использовать элемент списка по индексу
>> проверяет значение свойства-флага.
вызывает некоторые сомнения.


 
Alexander Panov ©   (2005-08-23 14:13) [22]

Fay ©   (23.08.05 13:57) [19]
Не хотелось бы показаться занудой, но мне кажется, что были некоторые причины, по которым Вы применили именно кр. секции, а не прекрасный во всех отношениях Suspend...


Конечно причины были-)
И главная - это показать, как можно делать правильно.
А про Suspend - Reindeer Moss Eater ©   (23.08.05 14:05) [20] уже показл, как делается без проблем защита кода только лишь при помощи Suspend.

Можно даже и без "усыпляния" потока обойтись. Для этого достаточно достаточно использовать спин-блокировку:

Flag1,Flag2 - Boolean;
Flag2 - флаг занятости текущим потоком, Flag1 - "Чужим потоком"

while not Flag2 do
begin
 while not Flag1 do ;
 Flag2 := True;
 Flag2 := not Flag1;
end;


 
Reindeer Moss Eater ©   (2005-08-23 14:15) [23]

Какие именно сомнения?
Вторичным потоком рулит первичный.
Он ему делает суспенд.
Список изменяется только когда вторичный поток уснул.
Фактически фторичному потоку даже знать не надо, что его усыпляют иногда.
Все что ему надо - проверить свойство-флаг перед использованием элемента списка.

А когда именнно поток уснул по часам - по барабану.


 
Alexander Panov ©   (2005-08-23 14:15) [24]

Fay ©   (23.08.05 14:11) [21]
вызывает некоторые сомнения.


В какой части вызывает сомнения?


 
Alexander Panov ©   (2005-08-23 14:19) [25]

Испроавляю код из [22]:
while not Flag2 do
begin
while Flag1 do ;
Flag2 := True;
Flag2 := not Flag1;
end;


 
Fay ©   (2005-08-23 14:44) [26]

2 Reindeer Moss Eater ©   (23.08.05 14:15) [23]
2 Alexander Panov ©   (23.08.05 14:15) [24]

Вы издеваетесь?!
Проверка какого-то там флага;
здесь мы уснули ...
а в это время со списком творят что-то;
... и проснулись
Используем элемент списка;
$опа


Да и не очень понятно, флаг проверять во сне, что-ли?


 
Reindeer Moss Eater ©   (2005-08-23 14:54) [27]

Да и не очень понятно, флаг проверять во сне, что-ли?

Все что ему надо - проверить свойство-флаг перед использованием элемента списка.


 
Fay ©   (2005-08-23 14:56) [28]

Reindeer Moss Eater ©   (23.08.05 14:54) [27]
А за что отвечает этот флаг (кстати)? И откуда уверенность, что флаг не изменится между его (флага) проверкой и обращением к списку?


 
Reindeer Moss Eater ©   (2005-08-23 15:03) [29]

MyList[Min(i,Flag)]


 
Fay ©   (2005-08-23 15:11) [30]

2 Reindeer Moss Eater ©   (23.08.05 15:03) [29]
Могу только пожелать Вам удачи. Она очень пригодится.


 
Alexander Panov ©   (2005-08-23 15:18) [31]

Fay ©   (23.08.05 15:11) [30]
Могу только пожелать Вам удачи. Она очень пригодится.


Не в удаче дело. Все, как в аптеке.
-----------------------------------

А весь этот разговор шел к тому, что путей решения может быть много. И не всегда то, что мы считаем неверным, неверно на самом деле. Надо только голову приложить.


 
Alexander Panov ©   (2005-08-23 15:20) [32]

Fay ©   (23.08.05 14:44) [26]
Используем элемент списка;
$опа


Что опа?

В данном случае используется блокировка на уровне элемента списка.
Если будет наложено условие, что элемент списка может быть удален извне, то будет использоваться блокировка на уровне всего списка.


 
Fay ©   (2005-08-23 15:22) [33]

2 Alexander Panov ©   (23.08.05 15:18) [31]
Этих голов уже нехилый курган сложено.
Хотя мне, честно говоря, по барабану - пишите, как хотите.


 
Fay ©   (2005-08-23 15:26) [34]

2 Alexander Panov ©   (23.08.05 15:20) [32]

Что ещё не понятно? Повторяю,  Вы не знаете, где именно уснёт поток, и пока это так, проверки ничего не значат. Этих "свойств-флагов" самих впору защищать.


 
Leonid Troyanovsky ©   (2005-08-23 15:34) [35]


> volser   (23.08.05 12:49) [4]
>
> > Ты лучше опиши, чего ты хочешь добиться, тогда можно будет
>
> > предложить метод решения.
>
> Я в потоке работаю со списком (прохожу по циклу от 0  до
> каунт - 1), но в главном потоке мне нужно этот список очистить.
> Если не останавливать поток, то естественно иногда выводит,
> что индекс вышел за пределы допустимых значений. Вот я и
> хочу


RTFM: TThreadList, например.
Защищает свои данные критической секцией.

--
Regards, LVT.


 
Alexander Panov ©   (2005-08-23 15:35) [36]

Fay ©   (23.08.05 15:26) [34]
Что ещё не понятно? Повторяю,  Вы не знаете, где именно уснёт поток, и пока это так, проверки ничего не значат.


Да неужели?
И кто же его усыплять будет? Дядя Вася?
А не мой ли поток будет его усыплять?
Может быть это Вы пишете программы так, что их невозможно контролировать, а у меня код в одном потоке знает, как работать с другими потоками, и что они делают в этот момент.

Может быть для написания двух строчек кода вместо одной надо излишне напрячься? Ну тогда увы. Так как это достаточно сложно, тогда дискусии неуместны. Я ретируюсь.


 
Leonid Troyanovsky ©   (2005-08-23 15:39) [37]


> Reindeer Moss Eater ©   (23.08.05 14:15) [23]

> А когда именнно поток уснул по часам - по барабану.


 А если он заснет посредине, скажем, Move?

Для синхронизации есть дофига API.

Кстати, даже четырехбайтовых значений положено InterLocked*

--
Regards, LVT.


 
Reindeer Moss Eater ©   (2005-08-23 15:43) [38]

А если он заснет посредине, скажем, Move?

А он сможет уснуть посреди Move?


 
Alexander Panov ©   (2005-08-23 15:43) [39]

Leonid Troyanovsky ©   (23.08.05 15:39) [37]
Для синхронизации есть дофига API.


Естественно, и намного эффективнее и правильнее использовать именно эти средства.

Leonid Troyanovsky ©   (23.08.05 15:39) [37]
А если он заснет посредине, скажем, Move?


Он сам заснет, что-ли?

Leonid Troyanovsky ©   (23.08.05 15:39) [37]
Кстати, даже четырехбайтовых значений положено InterLocked*


Это если используется блокировка Interlocked-функциями.


 
Fay ©   (2005-08-23 15:43) [40]

Reindeer Moss Eater ©   (23.08.05 15:43) [38]
он может уснуть ГДЕ УГОДНО



Страницы: 1 2 3 4 вся ветка

Форум: "Основная";
Текущий архив: 2005.09.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.011 c
14-1124688619
Guest_03
2005-08-22 09:30
2005.09.18
Подключил мобильник и чуть не сжег БП !


4-1122360846
Работник
2005-07-26 10:54
2005.09.18
Отключение дисков


14-1124880528
Korvet
2005-08-24 14:48
2005.09.18
Где скачать "Ras"


3-1123148932
Koralnik
2005-08-04 13:48
2005.09.18
Запрос в базу данных удаленного сервера


6-1110760527
antoxa
2005-03-14 03:35
2005.09.18
Подскажите на "чем из Delphi" писать для интернет (сервер Linux)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский