Сообщений: 5,862 
	Тем: 105 
	Зарегистрирован: Sep 2010
	
 Репутация: 
 13,014
	 
 
	
	
		Hint Написал:Из потоков нельзя просто так вызывать функции VCL. И нельзя просто так обращаться ко внешним данным (или вызывать функции, которые используют внешние данные). Все должно быть синхронизировано: или с использованием блокировок, или с посылкой сообщений в основной поток (который в свою очередь уже будет работать с общими данными). А можно пример? Как я понял, имеется ввиду CriticalSection, нет?
	  
	
	
	
	
 
 
	
	
	
		
	Сообщений: 220 
	Тем: 19 
	Зарегистрирован: Oct 2011
	
 Репутация: 
 2,462
	 
 
	
	
		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, ...
 
	
	
 
 
	
	
	
		
	Сообщений: 5,862 
	Тем: 105 
	Зарегистрирован: Sep 2010
	
 Репутация: 
 13,014
	 
 
	
		
		
		09-16-2012, 03:10 PM 
(Сообщение последний раз редактировалось: 09-16-2012, 04:19 PM   Zubastic.)
		
	 
	
		Вопрос немного не по теме: 
В программе есть встроенный апдейтер, в итоге касперский определяет программу как самообновляющееся троянское ПО. Впринципе решение - криптовать исполняемый файл, но есть ли что-то более удобное? 
 
Добавлено через 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.
	 
	
	
	
	
 
 
	
	
	
		
	Сообщений: 2,101 
	Тем: 40 
	Зарегистрирован: Apr 2008
	
 Репутация: 
 12,296
	 
 
	
	
		Дабы не гадить новой темой в разделе - подскажите по плюсовым (С++) потокам: 
1) Возможно ли ограничивать как то созданный поток ресурсами ПК (Ибо в некоторых случаях грузит проц в 100% (если использовать цикл в новом потоке)
 2) Возможно ли стартовать новый поток по таймеру, но при этом не глушить BaseThread?( Тупанул со Sleep) 
3) Мельком натыкался на инфу, что не стоит юзать CreateThread обычного WinAPI...Что с ним не так? К чему приводит? 
4) для чего многие описывают CloseHandle(Thread)? Поток же и так закроется при выполнении нужной задачи О_о (Или тут я чего-то не понял?) 
--- 
P.S - начал чуток познавать плюсы, но нет жесткой возможности много читать    Работа...
	  
	
	
	
	
 
 
	
	
	
		
	Сообщений: 343 
	Тем: 4 
	Зарегистрирован: Jan 2011
	
 Репутация: 
 2,824
	 
 
	
	
		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. 
	 
	
	
	
	
 
 
	
	
	
		
	Сообщений: 5,862 
	Тем: 105 
	Зарегистрирован: Sep 2010
	
 Репутация: 
 13,014
	 
 
	
	
		G1ta0, вообще как сделать самообновление без детектирования антивирем?
	 
	
	
	
	
 
 
	
	
	
		
	Сообщений: 343 
	Тем: 4 
	Зарегистрирован: Jan 2011
	
 Репутация: 
 2,824
	 
 
	
	
		Да они в любом случаем ругаются на апдейтеры самописные. Попробуй CreateProcess вместо ShellExecute.
	 
	
	
	
	
 
 
	
	
	
		
	Сообщений: 2,101 
	Тем: 40 
	Зарегистрирован: Apr 2008
	
 Репутация: 
 12,296
	 
 
	
	
		G1ta0;227644 Написал:К ошибкам выделения памяти, инфы тонна, в Delphi к слову также, надо юзать beginthread. Кстати пересев на _beginthread заметил кое какие улучшения в быстродействии вроде как    Правда размер компиленной программки вырос чуток    Ну то мелочи   
СПС за инфу!!!
 G1ta0;227644 Написал:Юзать приоритеты и Sleep/WaitFor... если нет полезной нагрузки. Каждая миллисекунда на весу    Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало   
	 
	
	
	
	
 
 
	
	
	
		
	Сообщений: 343 
	Тем: 4 
	Зарегистрирован: Jan 2011
	
 Репутация: 
 2,824
	 
 
	
	
		KilRoy Написал:Каждая миллисекунда на весу   Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало   Чтобы поток не отжирал весь проц, можно передавать периодически управление на другой поток (yield). Если действительно задача не может обойтись Sleep.
 http://msdn.microsoft.com/en-us/library/...s.85).aspx
	 
	
	
	
	
 
 
	 
 |