Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.17;
Скачать: CL | DM;

Вниз

Потоки мешаю друг другу   Найти похожие ветки 

 
Мирон ©   (2004-09-30 14:58) [0]

В проге запущен поток (делает бэкап некоего каталога на диске).
При запуске в проге второго подобного (оба экземпляры одного класса) - первый прекращает работу. Из-за чего это может быть? Заранее спасибо.


 
Ozone ©   (2004-09-30 15:02) [1]

А что делает 2-й поток?


 
Мирон ©   (2004-09-30 15:05) [2]


> А что делает 2-й поток?

бэкап другого каталога


 
Суслик ©   (2004-09-30 15:06) [3]

чую к посту 20 мы выясним все детали :)))
может быть даже кусочек кода получим


 
Суслик ©   (2004-09-30 15:08) [4]

Автору.

Только большая просьба - если соизволишь дать код, то не приводи листинг на 102 страницах. Сократи до размера разумного.


 
pasha_golub ©   (2004-09-30 15:10) [5]

Раз, два, три , четыре, пять - начинаю телепать:

"Вижу, вижу... Два потока обращаются к одному файлу в режиме монопольного доступа"


 
TUser ©   (2004-09-30 15:11) [6]


> то не приводи листинг на 102 страницах. Сократи до размера
> разумного.

До ближайшей круглой цифры


 
Мирон ©   (2004-09-30 15:12) [7]


> "Вижу, вижу... Два потока обращаются к одному файлу в режиме
> монопольного доступа"

Ни фига, потоки пишут разные каталоги в разные места


 
Суслик ©   (2004-09-30 15:14) [8]


> [5] pasha_golub ©   (30.09.04 15:10)

Слабак!
До телепата тебе далеко :)))
Ты лучше попробуй Мирону телепатировать код выложить...


 
pasha_golub ©   (2004-09-30 15:14) [9]

Мирон ©   (30.09.04 15:12) [7]
А мы это должны по наитию знать? :))


 
Суслик ©   (2004-09-30 15:15) [10]


>  [9] pasha_golub ©   (30.09.04 15:14)


> А мы это должны по наитию знать? :))

Учись, студент :)) Где тебе еще такие горизонты применения своих телепатических навыков приснятся?


 
Ozone ©   (2004-09-30 15:18) [11]

:) Хватит флудить. Давайте все дружно подождем кода!


 
pasha_golub ©   (2004-09-30 15:18) [12]

Суслик ©   (30.09.04 15:15) [10]
:0)

Ozone ©   (30.09.04 15:18) [11]
Раз, два, три , четыре, пять - начинаю кода ждать.


 
Суслик ©   (2004-09-30 15:20) [13]


> [12] pasha_golub ©   (30.09.04 15:18)

восемь тысяч девятьсот сотрок пять
восемь тысяч девятьсот сотрок шесть
восемь тысяч девятьсот сотрок семь
....

ЗЫ. Не будет кода


 
Суслик ©   (2004-09-30 15:20) [14]


> [12] pasha_golub ©   (30.09.04 15:18)

восемь тысяч девятьсот сотрок пять
восемь тысяч девятьсот сотрок шесть
восемь тысяч девятьсот сотрок семь
....

ЗЫ. Не будет кода


 
Romkin ©   (2004-09-30 15:21) [15]

Лучше я телепну:

TCoolTread.Execute;
begin
 while not Terminated do
   Syncronize;
end;

ТАк? :))))


 
Мирон ©   (2004-09-30 15:24) [16]

Ща, подождите, обстоятельно все напишу. Чтоб потом вопросов было меньше.


 
Суслик ©   (2004-09-30 15:24) [17]


>  [16] Мирон ©   (30.09.04 15:24)
> Ща, подождите, обстоятельно все напишу. Чтоб потом вопросов
> было меньше.

Ура!!!!
Так бы сразу :)))


 
pasha_golub ©   (2004-09-30 15:32) [18]

Суслик ©   (30.09.04 15:24) [17]
Эх, студент. :)
Ура, заработало (с) Матроскин


 
Мирон ©   (2004-09-30 15:49) [19]

Как уже все наверное протелепатировали, прога делает резервные копии каталогов.
Каждая задача запускается в отдельном потоке. Каждая задача реализована как класс (ну, пунктик у меня на счет ООП, что поделаешь...:-)).

Вот описание

TBackUP = class(TObject)
 private
   FDestination: string;
   FName: String;
   FSourche: String;
   FLastExec: TDate;
   Form: TfmBackUp;
   FActive: Boolean;
   FThread: TBackUpThread;
   procedure SetName(const Value: String);
   procedure SetSourche(const Value: String);
   procedure SetDestination(const Value: string);
   procedure SetActive(const Value: Boolean);
 public
   constructor Create(F: TfmBackUp);
   procedure GOBackUp;  // сама процедура копирования
   procedure SaveToStream(MS: TufMemoryStream);   //
   procedure LoadFromStream(MS: TufMemoryStream);
   procedure ShowPropertyes;   // отбражаем состояние на контролах формы (TfmBackup)
   property Active: Boolean read FActive write SetActive;
   property Destination: string read FDestination write SetDestination;  // папка, куда все копируем
   property LastExec: TDate read FLastExec write FLastExec;              
   property Name: String read FName write SetName;
   property Sourche: String read FSourche write SetSourche; // папка, откуда все копируем  
 end;

Описание класса потока

TBackUpThread = class(TThread)
 private
   FProfile: TBackUP;
   TotalFiles: Integer;
   CurrentFile: Integer;
   StartDir: String;
   CurrentDirName: String;
   CurrentFileName: String;            
 public
   constructor Create(AProfile: TBackUP);
   function FilesCount(Dir: String): Integer;  // функция возвращает количество файлов и папок в указанном каталоге
   procedure Execute; override;
   procedure ShowProgress;
 end;

Далее. При создании формы, из файла настроек считываются имеющиеся задания, для каждого из которых создается экземпляр TBackUp, указатель на него помещается в ListBox формы. При щелканьи на кнопке "GO" на форме. Выделенное получает Active := True.

Вот код

procedure TBackUP.SetActive(const Value: Boolean);
begin
   if FActive <> Value
   then begin
       FActive := Value;
       Form.btnRun.Enabled := not Value;
       Form.btnStop.Enabled := Value;
       Form.LB.Enabled := not Value;
       if Value
       then GOBackUp
       else FThread.Terminate;
   end;
end;

далее попадаем в

procedure TBackUP.GOBackUp;
begin
   FThread := TBackUpThread.Create(Self);
   FThread.Execute;
end;

далее

procedure TBackUpThread.Execute;
var
   SL: TStringList;
   //=============================================================
   procedure ScanDirectory(CurrBUF, Dir: String);
   var
       sr, srFiles, srDest, srSourche: TSearchRec;
       OldDate, NewDate: TDateTime;
       DestFileName, SourcheFileName: String;

   begin
       if Terminated
       then Exit;
       if Dir[Length(Dir)] <> "\"
       then Dir := Dir + "\";
       if CurrBUF[Length(CurrBUF)] <> "\"
       then CurrBUF := CurrBUF + "\";
       SL.Add("&#209;&#234;&#224;&#237;&#232;&#240;&#243;&#229;&#236; &#239;&#224;&#239;&#234;&#243;: " + Dir + sr.Name);
       if FindFirst(Dir + "*.*", faAnyFile, srFiles) = 0
       then begin
           try
               repeat
                   if (not ((srFiles.Attr and faDirectory) = faDirectory))
                   then begin
                       inc(CurrentFile);
                       CurrentFileName := srFiles.Name;
                       CurrentDirName := "..\" + ExtractRelativePath(StartDir, Dir);
                       SourcheFileName := Dir + srFiles.Name;
                       DestFileName := CurrBUF + srFiles.Name;
                       Synchronize(ShowProgress);
                       if not FileExists(DestFileName)
                       then begin
                           SL.Add("    &#202;&#238;&#239;&#232;&#240;&#243;&#229;&#236; &#244;&#224;&#233;&#235;:" + srFiles.Name);
                           if not CopyFile(PAnsiChar(SourcheFileName), PAnsiChar(DestFileName), False)
                           then SL.Add("&#205;&#229; &#243;&#228;&#224;&#235;&#238;&#241;&#252; &#241;&#234;&#238;&#239;&#232;&#240;&#238;&#226;&#224;&#242;&#252;");
                       end
                       else begin
                           if FindFirst(DestFileName, faAnyFile, srDest) = 0
                           then begin
                               try
                                   if (srDest.FindData.ftLastWriteTime.dwLowDateTime <> srFiles.FindData.ftLastWriteTime.dwLowDateTime)
                                       and (srDest.FindData.ftLastWriteTime.dwHighDateTime <> srFiles.FindData.ftLastWriteTime.dwHighDateTime)
                                   then begin
                                       SL.Add("&#206;&#225;&#237;&#238;&#226;&#235;&#255;&#229;&#236; &#244;&#224;&#233;&#235;: " + srFiles.Name);
                                       if not CopyFile(PAnsiChar(SourcheFileName), PAnsiChar(DestFileName), False)
                                       then SL.Add("&#205;&#229; &#243;&#228;&#224;&#235;&#238;&#241;&#252; &#238;&#225;&#237;&#238;&#226;&#232;&#242;&#252;");
                                   end;
                               finally
                                   SysUtils.FindClose(srDest);
                               end;
                           end;
                       end;
                   end;
               until FindNext(srFiles) <> 0
           finally
               SysUtils.FindClose(srFiles);
           end;
       end;
       if FindFirst(Dir + "*.*", faHidden or faDirectory, sr) = 0
       then begin
           try
               repeat
                   if (sr.Attr and faDirectory = faDirectory) and (sr.Name[1] <> ".")
                   then begin
                       inc(CurrentFile);
                       Synchronize(ShowProgress);
                       ForceDirectories(CurrBUF + sr.Name);
                       ScanDirectory(CurrBUF + sr.Name, Dir + sr.Name);
                   end;
               until FindNext(sr) <> 0
           finally
               SysUtils.FindClose(sr);
           end;
       end;
   end;
begin
   if DirectoryExists(FProfile.FSourche)
   then begin
       SL := TStringList.Create;
       try
           TotalFiles := FilesCount(FProfile.Sourche);
           SL.Add("&#205;&#224;&#233;&#228;&#229;&#237;&#238; &#244;&#224;&#233;&#235;&#238;&#226; &#232; &#239;&#224;&#239;&#238;&#234;: " + IntToStr(TotalFiles));
           CurrentFile := 0;
           ScanDirectory(FProfile.FDestination, FProfile.Sourche);
           Terminate;
           Synchronize(ShowProgress);
       finally
           try
               SL.SaveToFile(ExtractFilePath(Application.ExeName) + FProfile.Name + ".txt");
           finally
               SL.Free;
           end;
       end;
   end;
end;


 
Мирон ©   (2004-09-30 15:51) [20]

так отображается состояние потока при "Synchronize(ShowProgress);"

procedure TBackUpThread.ShowProgress;
begin
   Self.Suspend;
   Application.ProcessMessages;
   Self.Resume;
   if FProfile.Form.LB.ItemIndex = FProfile.Form.LB.Items.IndexOfObject(FProfile)
   then begin
       if Self.Terminated
       then begin
            FProfile.Active := False;
            FProfile.Form.PB.Position := 0;
            FProfile.Form.lblFolder.Caption := "&#207;&#224;&#239;&#234;&#224;:";
            FProfile.Form.lblFile.Caption := "&#212;&#224;&#233;&#235;:";
       end
       else begin
           FProfile.Form.PB.Min := 0;
           FProfile.Form.PB.Max := TotalFiles;
           FProfile.Form.PB.Position := CurrentFile;
           FProfile.Form.lblFolder.Caption := "Папка: " + CurrentDirName;
           FProfile.Form.lblFile.Caption := "Файл: " + CurrentFileName;
       end;
   end;


 
Суслик ©   (2004-09-30 15:53) [21]


> procedure TBackUP.GOBackUp;
> begin
>    FThread := TBackUpThread.Create(Self);
>    FThread.Execute;> end;


Ты неправильно запускаешь потоки.
Читай примеры.

ЗЫ. Ты не показал тело конструктора потока, но думаю в данном случае resume подойдет.

Как сейчас есть у тебя нет никакого потока - поток у тебя один :)))


 
Суслик ©   (2004-09-30 15:57) [22]


> Self.Suspend;
>    Application.ProcessMessages;
>    Self.Resume;

это ерунда какая-то :)))

зачем ты в потоке вызываешь terminate? Вообще ерунда.

Совет. Серьезно займись изучением класса TThread. См. примеры. См. код реализации в classes.pas.


 
Мирон ©   (2004-09-30 15:58) [23]

конструктор

constructor TBackUpThread.Create(AProfile: TBackUP);
begin
   inherited Create(True);
   Priority := tpLower;
   FProfile := AProfile;
   StartDir := FProfile.FSourche;
end;


 
Мирон ©   (2004-09-30 16:00) [24]

Поставил "Resume" - заработало. Спасибо.


 
Суслик ©   (2004-09-30 16:01) [25]


>  [24] Мирон ©   (30.09.04 16:00)
> Поставил "Resume" - заработало. Спасибо.

Рано говорить спасибо.

Если хочешь сделать нормальную реализацию с пониманием дела тебе нужно сильно переработать твой код. Хотя, дело твое.


 
Digitman ©   (2004-09-30 16:05) [26]


> Мирон


Self.Suspend;
Application.ProcessMessages;
Self.Resume;


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


>    inherited Create(True);


вот ты создал "спящий" поток, а где же его "пробуждение" ?


 
Мирон ©   (2004-09-30 16:08) [27]

А где поток уничтожать-то, когда он отработает?


 
Суслик ©   (2004-09-30 16:10) [28]


>  [27] Мирон ©   (30.09.04 16:08)
> А где поток уничтожать-то, когда он отработает?

Ставь объекту потока FreeOnTerminat = true и дело с концом.
Сам уничтожится.


 
Erik1 ©   (2004-09-30 16:11) [29]

Удалено модератором


 
Мирон ©   (2004-09-30 16:12) [30]

было
procedure TBackUP.GOBackUp;
begin
   FThread := TBackUpThread.Create(Self);
   FThread.Execute;
end;


И, короче, кнопочки на форме не нажимались.

Self.Suspend;
Application.ProcessMessages;
Self.Resume;


помогло рещить проблему

исправил
procedure TBackUP.GOBackUp;
begin
   FThread := TBackUpThread.Create(Self);
   FThread.Resume;
end;


вроде фунциклирует


 
Суслик ©   (2004-09-30 16:13) [31]


> И, короче, кнопочки на форме не нажимались.
>
> Self.Suspend;
> Application.ProcessMessages;
> Self.Resume;

Конечно не нажимались, у тебя же тело методе Execute выполнялось в основном кодовом потоке :)))


 
Digitman ©   (2004-09-30 16:16) [32]


> Self.Suspend;
> Application.ProcessMessages;
> Self.Resume;
>
> помогло рещить проблему


все понятно - великий и могучий метод научного тыка

нет бы документацию почитать


 
Мирон ©   (2004-09-30 16:18) [33]


> Конечно не нажимались, у тебя же тело методе Execute выполнялось
> в основном кодовом потоке :)))


Уже допер. Ладно, не ржите. Врядли кто с первого раза делает все правильно.


 
Суслик ©   (2004-09-30 16:20) [34]


> Уже допер. Ладно, не ржите. Врядли кто с первого раза делает
> все правильно.

Кто-то и со второго не все делает правильно, особенно если документацию не читал.

Без обид. Ну ведь это правда? :)


 
pasha_golub ©   (2004-09-30 16:23) [35]

Мирон, заглянь в папку Demos. Пример тама отличный. Я сам по нему вкуривал.


 
Мирон ©   (2004-09-30 16:25) [36]

Да читал я её. Если бе не читал, не наваял бы даже такого. Просто нету времени на серьезное изучение - завтра надо показать работающую прогу. А там дадут пару дней на ловлю багов, тогда и почитаю...



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

Текущий архив: 2004.10.17;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.058 c
1-1096303053
Nkrd
2004-09-27 20:37
2004.10.17
активный richedit


6-1092235218
Павел
2004-08-11 18:40
2004.10.17
Динамические массивы.


14-1096370328
DSKalugin
2004-09-28 15:18
2004.10.17
Россия получит Windows для бедных


1-1096541936
Мирон
2004-09-30 14:58
2004.10.17
Потоки мешаю друг другу


1-1097057457
456
2004-10-06 14:10
2004.10.17
как таскать (drag and drop) кнопки (которые созданы динамически)