Сообщений: 5,863
Тем: 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,863
Тем: 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 - начал чуток познавать плюсы, но нет жесткой возможности много читать ![Sad Sad](https://forum.zone-game.info/images/smilies/sad.png) Работа...
Сообщений: 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,863
Тем: 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 заметил кое какие улучшения в быстродействии вроде как ![Smile Smile](https://forum.zone-game.info/images/smilies/smile.png) Правда размер компиленной программки вырос чуток ![Sad Sad](https://forum.zone-game.info/images/smilies/sad.png) Ну то мелочи ![Smile Smile](https://forum.zone-game.info/images/smilies/smile.png)
СПС за инфу!!!
G1ta0;227644 Написал:Юзать приоритеты и Sleep/WaitFor... если нет полезной нагрузки. Каждая миллисекунда на весу ![Smile Smile](https://forum.zone-game.info/images/smilies/smile.png) Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало
Сообщений: 343
Тем: 4
Зарегистрирован: Jan 2011
Репутация:
2,824
KilRoy Написал:Каждая миллисекунда на весу Но всё же слип пришлось использовать, ибо это был хаос...Но меня не это интересовало ![Wink Wink](https://forum.zone-game.info/images/smilies/wink.png) Чтобы поток не отжирал весь проц, можно передавать периодически управление на другой поток (yield). Если действительно задача не может обойтись Sleep.
http://msdn.microsoft.com/en-us/library/...s.85).aspx
|