Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Работа с потоками в delphi
#31
Hint Написал:Из потоков нельзя просто так вызывать функции VCL. И нельзя просто так обращаться ко внешним данным (или вызывать функции, которые используют внешние данные). Все должно быть синхронизировано: или с использованием блокировок, или с посылкой сообщений в основной поток (который в свою очередь уже будет работать с общими данными).
А можно пример? Как я понял, имеется ввиду CriticalSection, нет?
Ответ
#32
Zubastic Написал:А можно пример? Как я понял, имеется ввиду CriticalSection, нет?
Да, это и есть блокировки (enter / leave или lock / unlock).

Пример (что первым попалось в коде). Есть поток, отвечающий за связь с веб-сервером (класс TWebClient). Если рабочий поток, собирающий данные. Рабочий поток для отправки данных вызывает метод AddUserData.

Код:
procedure TWebClient.AddUserData(Line: string);
begin
  UserData.Lock;
  try
    UserData.Add(line);
  finally
    UserData.Unlock;
  end;
end;

UserData - private свойство класса TWebClient.

Поток TWebClient с определенным интервалом соединяется с сервером и вызывает свой метод SendUserData:
Код:
function TWebClient.SendUserData: Integer;
var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    SL.Clear;
    UserData.Lock; // Блокируем объект
    try
      SL.AddStrings(UserData); // Копируем содержимое в локальный объект
      UserData.Clear;
    finally
      UserData.Unlock; // Снимаем блокировку
    end;    
    
    if SL.Count > 0 then
      begin
        Result := UploadData(SL);
        if Result = -1 then
          begin
            UserData.Lock;
            try
              UserData.AddStrings(SL);
            finally
              UserData.Unlock;
            end;            
          end;
      end
    else Result := 0;
  finally
    FreeAndNil(SL);
  end;
end;

Общие данные - объект UserData (свой класс TSafeStringList). При работе с ним используются критические секции (сначала Lock, потом Unlock).

Код:
TSafeStringList = class(TStringList)
  private
    CriticalSection: TCriticalSection;
  public
    procedure Lock;
    procedure Unlock;
    constructor Create;
    destructor Destroy; override;
  end;
...
constructor TSafeStringList.Create;
begin
  inherited Create;
  CriticalSection := TCriticalSection.Create;
end;

destructor TSafeStringList.Destroy;
begin
  CriticalSection.Free;
  inherited Destroy;
end;

procedure TSafeStringList.Lock;
begin
  CriticalSection.Enter;
end;

procedure TSafeStringList.Unlock;
begin
  CriticalSection.Leave;
end;
hLaPEx, Evermore, hAuthD, L2on, ...
Ответ
#33
Вопрос немного не по теме:
В программе есть встроенный апдейтер, в итоге касперский определяет программу как самообновляющееся троянское ПО. Впринципе решение - криптовать исполняемый файл, но есть ли что-то более удобное?

Добавлено через 1 час 8 минут
[SRC="pascal"] if ver<Memo3.Lines[0] then
begin
Stream:=TMemoryStream.Create;
Stream.LoadFromFile(paths+'Updater.exe');
Stream2:=TMemoryStream.Create;
try
idHTTP1.Get(url, Stream2); //Загрузка в поток данных из сети
if Stream.Size <> Stream2.Size then
begin
DeleteFile(paths+'Updater.exe');
Stream2.SaveToFile(paths+'Updater.exe');
end;
ShellExecute(Form1.Handle,'open', pchar(paths+'Updater.exe'), nil, nil, SW_SHOWNORMAL);
Application.Terminate;
except
on E:Exception do
begin
if FileExists(paths+'error.log') then Memo3.Lines.LoadFromFile(paths+'error.log');
if idHTTP1.ResponseCode = -1 then Memo3.Lines.Add(DateTimeToStr(Now)+' - Не удается скачать апдейтер. (-1)')
else if idHTTP1.ResponseCode = 404 then Memo3.Lines.Add(DateTimeToStr(Now)+' - Апдейтер не найден. (404)')
else Memo3.Lines.Add(DateTimeToStr(Now)+' - Error: '+E.ClassName+'. Msg: '+E.Message);
Memo3.Lines.SaveToFile(paths+'error.log');
end;
end;
Stream.Free;
Stream2.Free;
end;[/SRC]
Ругается конкретно на строчку с ShellExecute.
Ответ
#34
Дабы не гадить новой темой в разделе - подскажите по плюсовым (С++) потокам:
1) Возможно ли ограничивать как то созданный поток ресурсами ПК (Ибо в некоторых случаях грузит проц в 100% (если использовать цикл в новом потоке)
2) Возможно ли стартовать новый поток по таймеру, но при этом не глушить BaseThread?(Тупанул со Sleep)
3) Мельком натыкался на инфу, что не стоит юзать CreateThread обычного WinAPI...Что с ним не так? К чему приводит?
4) для чего многие описывают CloseHandle(Thread)? Поток же и так закроется при выполнении нужной задачи О_о (Или тут я чего-то не понял?)
---
P.S - начал чуток познавать плюсы, но нет жесткой возможности много читать Sad Работа...
Ответ
#35
KilRoy Написал:1) Возможно ли ограничивать как то созданный поток ресурсами ПК (Ибо в некоторых случаях грузит проц в 100% (если использовать цикл в новом потоке)
Юзать приоритеты и Sleep/WaitFor... если нет полезной нагрузки.

KilRoy Написал:3) Мельком натыкался на инфу, что не стоит юзать CreateThread обычного WinAPI...Что с ним не так? К чему приводит?
К ошибкам выделения памяти, инфы тонна, в Delphi к слову также, надо юзать beginthread.

KilRoy Написал:4) для чего многие описывают CloseHandle(Thread)? Поток же и так закроется при выполнении нужной задачи О_о (Или тут я чего-то не понял?).
Незакрытый хендл порождает утечку объекта: http://msdn.microsoft.com/en-us/library/...85%29.aspx
Цитата:The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.
Ответ
#36
G1ta0, вообще как сделать самообновление без детектирования антивирем?
Ответ
#37
Да они в любом случаем ругаются на апдейтеры самописные. Попробуй CreateProcess вместо ShellExecute.
Ответ
#38
G1ta0;227644 Написал:К ошибкам выделения памяти, инфы тонна, в Delphi к слову также, надо юзать beginthread.
Кстати пересев на _beginthread заметил кое какие улучшения в быстродействии вроде как Smile Правда размер компиленной программки вырос чуток Sad Ну то мелочи Smile
СПС за инфу!!!

G1ta0;227644 Написал:Юзать приоритеты и Sleep/WaitFor... если нет полезной нагрузки.
Каждая миллисекунда на весу Smile Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало Wink
Ответ
#39
KilRoy Написал:Каждая миллисекунда на весу Smile Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало Wink
Чтобы поток не отжирал весь проц, можно передавать периодически управление на другой поток (yield). Если действительно задача не может обойтись Sleep.

http://msdn.microsoft.com/en-us/library/...s.85).aspx
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  c# работа с бд Boris2105 4 1,929 05-26-2017, 05:35 PM
Последний пост: kpNemo
  Delphi 10.1 Berlin FREE Agares 2 2,189 01-12-2017, 09:58 PM
Последний пост: HiredKiller
  Delphi двунаправленный список Blacksoul 10 3,677 10-12-2016, 11:23 PM
Последний пост: flopix
  WinSocket delphi 7 HiredKiller 1 1,782 09-18-2015, 01:11 PM
Последний пост: flopix
  Delphi - XTreme Remote Controller Source OPPAIN 6 3,209 11-09-2012, 07:51 PM
Последний пост: OPPAIN
  работа с input SmokeeLow 1 1,838 11-24-2011, 07:19 PM
Последний пост: PROGRAMMATOR
  Delphi weTr1k 0 1,961 03-13-2011, 05:18 AM
Последний пост: weTr1k

Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)