Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 41 42 43 44 45 46 47 48 [49] 50   вперед  Ctrl
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
rgreat
Угадай что будет c диском c: ;)

Это одна из причин, по которой я её никогда не использую :)
26 ноя 19, 21:06    [22026101]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
rgreat
Member

Откуда:
Сообщений: 6078
alekcvp,

Ну "никогда" это ты загнул.

Просто надо быть аккуратным.
26 ноя 19, 21:36    [22026110]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
rgreat
alekcvp,

Ну "никогда" это ты загнул.

Просто надо быть аккуратным.


Проще обычный if написать, чем каждый раз думать чем чревато выполнение обоих веток.
26 ноя 19, 22:42    [22026140]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
rgreat
Member

Откуда:
Сообщений: 6078
Когда входные параметры - константы особо думать не требуется.
26 ноя 19, 22:44    [22026144]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Василий 2
Member

Откуда:
Сообщений: 1016
alekcvp
Проще обычный if написать, чем каждый раз думать чем чревато выполнение обоих веток.

Ага, особенно в конструкциях типа
Log('Something happened'+IfThen(Msg<>'', ': '+Msg)+IfThen(ErrCode<>0, ', err #'+Inttostr(ErrCode)))
27 ноя 19, 10:48    [22026372]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
rgreat
Когда входные параметры - константы особо думать не требуется.
Сегодня константы, завтра решили переделать на функции и привет.
А когда прям совсем-совсем константы, то я вместо IIF использую такое:
const 
  SomeConditionalFlags: array [Boolean] of Integer = (FLAGS_IF_FALSE, FLAGS_IF_TRUE);
...
  Flags := SomeConditionalFlags[<condition>];
Не так наглядно, зато неопасно.
27 ноя 19, 10:51    [22026380]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
Василий 2
alekcvp
Проще обычный if написать, чем каждый раз думать чем чревато выполнение обоих веток.

Ага, особенно в конструкциях типа
Log('Something happened'+IfThen(Msg<>'', ': '+Msg)+IfThen(ErrCode<>0, ', err #'+Inttostr(ErrCode)))
Ну я и говорил: "узкоприменимая".
27 ноя 19, 10:53    [22026384]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11984
alekcvp
А когда прям совсем-совсем константы, то я вместо IIF использую такое:
Аналогично
27 ноя 19, 16:12    [22026806]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Василий 2
Member

Откуда:
Сообщений: 1016
Не то чтобы лажанулся, а скорее наткнулся на подводный камень.
В большой многопоточной софтине начались тормоза при обработке - данные поступали быстрее, чем обрабатывались. Расследуя, выяснил, что все упиралось в Format дробных чисел. Переделал на FormatFloat, но почти не помогло. Долго ковырялся с бенчмарками, но существенно ускорить не получилось. Уже начал лазить по FastCode (безуспешно кстати - у них есть только чтение флоата из строки), когда вспомнил про старую добрую турбопаскалевскую Str. О, чудо! Она дала почти 4-кратное ускорение! Но что самое забавное, на изолированных бенчах прироста никакого нет. Судя по всему, это один из тех случаев, когда функция интенсивно использует менеджер памяти, а FastMM не очень хорош в многопоточной среде
4 дек 19, 15:01    [22032139]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Vlad F
Member

Откуда:
Сообщений: 1320
Василий 2,

А теперь если переделать на StrFmt(), входные буферы для которой распределить ДО начала работы многопоточного конвейера индивидуально для каждого потока, то можно добиться настоящей скорости.)))
4 дек 19, 15:37    [22032189]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Василий 2
Member

Откуда:
Сообщений: 1016
Vlad F
Василий 2,

А теперь если переделать на StrFmt(), входные буферы для которой распределить ДО начала работы многопоточного конвейера индивидуально для каждого потока, то можно добиться настоящей скорости.)))

Едва ли...
FormatFloat > FloatToTextFmt > FloatToDecimal
StrFmt > WideFormatBuf > FloatToText > FloatToDecimal (взрыв мозга можно получить блин, пока в этих переплетениях разношерстных функций разберешься).

Причем в FormatFloat и так запись в статический буфер, выигрыш можно получить разве что если вместо
total := total + Format(value)
делать форматирование сразу в нужную ячейку
FormatBuf(@total[curr], fmt, value)

В теории можно попробовать, но пока я слишком доволен функцией Str )) причем она еще и паддинг слева умеет делать.
4 дек 19, 16:18    [22032240]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Vlad F
Member

Откуда:
Сообщений: 1320
Василий 2,

Ты ничего не понял, StrFmt() помещает результаты своих вычислений в передаваемый ей, заранее приготовленный, буфер. В отличие от Str(), конструирующей новую строку, обращаясь к менеджеру памяти.
Не, но все это только, если нужно достичь настоящей скорости.))

Сообщение было отредактировано: 4 дек 19, 16:41
4 дек 19, 16:39    [22032288]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Василий 2
Member

Откуда:
Сообщений: 1016
Vlad F, всё я понял. Str, кстати, оперирует ShortString-ами, тч менеджер не дергает. Но для соединения с аккумулятором, конечно, приходится перегонять в string. Тоже есть куда оптимизировать, в принципе.
4 дек 19, 17:09    [22032335]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Vlad F
Member

Откуда:
Сообщений: 1320
Василий 2,
Настаивать далее смысла не вижу, решение для форматирования без обращения к менеджеру памяти приведено, ну а далее sapienti sat.))
4 дек 19, 20:29    [22032524]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 4136
Переименование файла:

rm /mnt/fsb/rod2015/database.db database_2019-12-15.db
15 дек 19, 14:04    [22040665]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
JaDi,

rm и mv перепутать - это как-то жётско...
15 дек 19, 18:16    [22040743]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11984
Вот такой класс

+
type
  TTest = class
  strict private
    class var
      FEvent: THandle;
      FThread: TThread;
  strict private
    class constructor Create;
    class destructor Destroy;
    class procedure WaitProc; static;
  end;

{ TTest }

class constructor TTest.Create;
begin
  FEvent := CreateEvent(nil, False, False, nil);
  FThread := TThread.CreateAnonymousThread(WaitProc);
  FThread.FreeOnTerminate := False;
  FThread.Start;
end;

class destructor TTest.Destroy;
begin
  SetEvent(FEvent);
  FThread.Free;
end;

class procedure TTest.WaitProc;
begin
  WaitForSingleObject(FEvent, INFINITE);
end;
засовываем в dll и получаем дедлок при вызове FreeLibrary.

FThread.Free вызывает внутри WaitForSingleObject(FThread.Handle), а ExitThread вызывает RtlFreeAnsiString, которая обращается к критической секции. А эта секция уже заблокирована вызовом FreeLibrary
16 дек 19, 17:03    [22041438]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
Квейд
Member

Откуда: Kyiv, Ukraine
Сообщений: 5367
чччД

А еще Microsoft борется с программистами, чтобы они не могли свое окошко сдалать Topmost. Свернуть - можно, а развернуть гарантированно "поверх всего" - фиквам. ShowWindow(), да-да. Переодически находим способы, как добиться. Но MS-soft выпускает обновления, после которых наши придумки не срабатывают... То есть, в разрезе предыдущей задачи - после ожидания не всегда получается "интегратор" вытянуть поверх остальных окон...
Так пробовали?

procedure BringWndToFront(AWindow: HWND);
var
  hCurrWnd: HWND;
  iMyTID, iCurrTID: Integer;
begin
  iMyTID := GetCurrentThreadID;
  hCurrWnd := GetForegroundWindow;
  iCurrTID := GetWindowThreadProcessId(hCurrWnd, nil);

  // "Windows NT 5.0 and later: An application cannot force a window to the foreground
  // while the user is working with another window. Instead, SetForegroundWindow will activate
  // the window (see SetActiveWindow) and call the FlashWindowEx function to notify the user."
  // So, we must make Windows think that our process is active...

  if iMyTID <> iCurrTID then
  begin
    AttachThreadInput(iMyTID, iCurrTID, True);
    if IsIconic(AWindow) then
      ShowWindow(AWindow, SW_RESTORE);
    SetForegroundWindow(AWindow);
    AttachThreadInput(iMyTID, iCurrTID, False);
  end
  else
    SetForegroundWindow(AWindow);
end;
16 дек 19, 18:03    [22041474]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4236
_Vasilisk_
Вот такой класс

+
type
  TTest = class
  strict private
    class var
      FEvent: THandle;
      FThread: TThread;
  strict private
    class constructor Create;
    class destructor Destroy;
    class procedure WaitProc; static;
  end;

{ TTest }

class constructor TTest.Create;
begin
  FEvent := CreateEvent(nil, False, False, nil);
  FThread := TThread.CreateAnonymousThread(WaitProc);
  FThread.FreeOnTerminate := False;
  FThread.Start;
end;

class destructor TTest.Destroy;
begin
  SetEvent(FEvent);
  FThread.Free;
end;

class procedure TTest.WaitProc;
begin
  WaitForSingleObject(FEvent, INFINITE);
end;

засовываем в dll и получаем дедлок при вызове FreeLibrary.

FThread.Free вызывает внутри WaitForSingleObject(FThread.Handle), а ExitThread вызывает RtlFreeAnsiString, которая обращается к критической секции. А эта секция уже заблокирована вызовом FreeLibrary
В finalizatin, что-ли, поток останавливается?
Тогда дело не в этом, или как минимум не только в этом.

автор
Because DLL notifications are serialized, entry-point functions should not attempt to communicate with other threads or processes. Deadlocks may occur as a result.
https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain
17 дек 19, 02:17    [22041713]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
alekcvp
Member

Откуда:
Сообщений: 2262
Квейд
  // "Windows NT 5.0 and later: An application cannot force a window to the foreground
  // while the user is working with another window. Instead, SetForegroundWindow will activate
  // the window (see SetActiveWindow) and call the FlashWindowEx function to notify the user."
  // So, we must make Windows think that our process is active...

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

- Пап, а правда виндовс - многозадачная среда?
- Да сынок.
- А как это, покажи?..
- Сейчас сынок, только дискетка доформатируется (С)
17 дек 19, 10:22    [22041842]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11984
YuRock
Тогда дело не в этом, или как минимум не только в этом.
Как же не в этом, если ты сам привел цитату с MSDN?
17 дек 19, 16:58    [22042353]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4236
_Vasilisk_
YuRock
Тогда дело не в этом, или как минимум не только в этом.
Как же не в этом, если ты сам привел цитату с MSDN?
Ну я имел ввиду - именно в том, что написано в мсдн.
Про RtlFreeAnsiString там ничего нет, конечно.
17 дек 19, 17:14    [22042368]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11984
YuRock,

В МSDN сказано, что обращение к другим потокам из DllMain может привести к дедлоку. Вот у меня привело.

В конечном счете я сделал так
class destructor TTest.Destroy;
begin
  if (FThread <> nil) and IsLibrary then begin
    FThread.FreeOnTerminate := True;
    FThread := nil;
  end;
  Finalize;
end;

class procedure TTest.Finalize;
begin
  SetEvent(FEvent);
  FreeAndNil(FThread);
end;

Т.е. желателен явный вызов TTest.Finalize. Ну а если его не произошло, то убираем ожидание завершения второго потока
17 дек 19, 17:32    [22042399]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4236
_Vasilisk_
В МSDN сказано, что обращение к другим потокам из DllMain может привести к дедлоку. Вот у меня привело.
Ну да.
Может, через раз. У меня много раз такое было.
Пока я не взял в привычку экспортировать доп. функцию и явно вызывать ее перед FreeLibrary.
И в ней финализировать всё.
18 дек 19, 01:47    [22042678]     Ответить | Цитировать Сообщить модератору
 Re: Топик "как я лажанулся"  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1175
_Vasilisk_

В МSDN сказано, что обращение к другим потокам из DllMain может привести к дедлоку.


Да и в EXE в секциях initialization и finalization лучше не пытаться создавать / останавливать потоки. Иначе иногда с программой творятся чудеса :)
18 дек 19, 19:44    [22043565]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 41 42 43 44 45 46 47 48 [49] 50   вперед  Ctrl
Все форумы / Delphi Ответить