powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus: коннект в потоке
125 сообщений из 125, показаны все 5 страниц
Lazarus: коннект в потоке
    #39457066
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужики, хотел внести для себя ясность в вопросе, которым только начал заниматься.

В приложении на главной форме FrmMain лежит TIBDatabase. Делаю коннект потоке (схематично)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TMyThread.Execute;
begin
  try
    FrmMain.IBDatabase.Connected:= True;
  except
    //bla-bla-bla
  end;
end;  



Соответственным образом коннекчусь к таблям.
Под виндой проблем нет, под никсами приложение валится через раз.

Поэтому хотел уточнить, это корректный код? Если создавать компоненты доступа динамически (объявив, как приватные поля класса TMyThread, типа FIBDatabase), то после уничтожения этого экземпляра потока FIBDatabase тоже умрет?
=================
Док.

Win7 Ultim x64/Deb 8.7 i386:
FB 3.0.2.32703, диалект 3, SS(win)/SC(Deb),
Lazarus 1.9(r.54844); FPC 3.1.1 (r.36160), IBX by -Rik-; IBE 2016.5.14.1
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457074
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В потоке только подключение?
Как потом с базой идет работа? Как форма узнает о результате?

Докпосле уничтожения этого экземпляра потока FIBDatabase тоже умрет?
Вряд-ли, т.к. поток не компонент. Его не указать владельцем (чтоб он всех своих за собой "забрал").
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457080
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanВ потоке только подключение?
нет, там работа с таблями: селекты, апдейты, выполнение процедур на сервере
wadmanКак форма узнает о результате?
о каком результате речь?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457082
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доко каком результате речь?
О результате работы потока. База-то на форме?

П.С. Если работа вся в потоке, то я-бы все необходимое для этой работы в потоке и создавал/удалял.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457085
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanО результате работы потока. База-то на форме?
Ну, естессно. В стартовом посте написал. После коннекта и пары проверок все селекты в гридах отображаются корректно. Вот только на Дебе падает через раз.

Откатиться, что ли, на предыдущие релизы Лазаря? Или попробовать UIB вместо IBX - ума не приложу...
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457093
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокПосле коннекта и пары проверок все селекты в гридах отображаются корректно.
Это же соединение потом в визуальной части используется? Если да, то как результат работы потока обрабатывается?
Из стартового поста не видно как реально используется поток и база.
ДокИли попробовать UIB вместо IBX - ума не приложу...
Вряд-ли это поможет.
ДокВот только на Дебе падает через раз.
С какой ошибкой?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457135
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanЭто же соединение потом в визуальной части используется? Если да, то как результат работы потока обрабатывается?
В потоке поэтапно проходит сначала коннект к базе, затем проверки (грузятся настройки юзверя для отображения ), затем открывается табля с гридом на форме и поток завешается и умирает

wadmanС какой ошибкой?
доберусь до дома, покажу
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457189
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. С одним коннектом может работать только один поток
2. Если несколько потоков создают коннекты, то эта процедура должна быть синхронизирована единым мьютексом
3. Пункт 2 распространяется на весь процесс. И если коннекты создаются в разных dll, то также должен использоваться единый мьютекс
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457222
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_, wadman
там код элементарный (на комменты не обращайте внимание, потом потру лишнее)

сам коннект
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
    { TDataMsg }

    TDataMsg = record
      Msg: DWord;
      WParam: Word;
      LParam: NativeInt;
    end;

    //вариант сценария работы дополнительного потока
    MyThreadTarget = (mttConnectDB, mttDisconnectDB, mttOpenDSet);   

//==========================
procedure TMyThread.Execute;
var MyMsg: TDataMsg;
    ErrMsg: String;
    i: Integer;
begin
  //реализуем тот или иной функционал потока в зависимости от заданной цели
  case FThreadTarget of
 {======================================================================================}
    //коннект к базе и основным таблицам
    mttConnectDB:
      try {цикл коннекта к базе и проверок}
        //задаем параметры коннекта
        with FrmMain.DBase_main do
          begin
            DatabaseName:= FDbName;
            LibraryName:= FLibName;
            Params.Add('lc_ctype=' + FChrSet);//чарсет коннекта
            Params.Add('user_name=' + FUsrNm);//имя юзера
            Params.Add('password=' +FPW);//пароль
            if Trim(FUsrRole) <> ''
              then Params.Add('sql_role_name=' + FUsrRole);//роль, если задана
          end;

        //запускаем фоновый поток коннекта
        try {коннект к базе данных}
          //коннектимся к базе (передаем сообщение в LabelMsg)
          MyMsg.LParam:= NewString('Коннектимся к базе данных');
          SendMessage(FrmMain.Handle, WM_GETFORSPLASHSTR_MSG, 0, MyMsg.LParam);

          //спрячем левую кнопку на сплэше
          MyMsg.WParam:= 0;
          MyMsg.LParam:= NewString('');
          SendMessage(FrmMain.Handle, WM_GETFORBTNLEFT_MSG, MyMsg.WParam, MyMsg.LParam);

          //текст для правой кнопки
          MyMsg.LParam:= NewString('Прервать');
          MyMsg.WParam:= 1;
          SendMessage(FrmMain.Handle, WM_GETFORBTNRIGHT_MSG, MyMsg.WParam, MyMsg.LParam);

          Sleep(1000);

          if not FrmMain.DBase_main.Connected then FrmMain.DBase_main.Connected:= True;

        except {коннект к базе данных}
           on E:EIBError do
             begin
               case EIBError(E).IBErrorCode of
         335544344: ErrMsg:= 'Не могу подключиться к указанному файлу базы данных. ' +
                             'Возможно, его уже успели переименовать, переместить, удалить или у вас нет на него прав';
         335544472: ErrMsg:= 'Введенный пароль не соответствует вашему логину. Уточните ваш логин и ' +
                             'пароль у администратора базы данных';
                 else
                    ErrMsg:= {$IFDEF UNIX} E.Message; {$ELSE} WinCPToUTF8(E.Message); {$ENDIF}
               end;


               //передаем текст сообщения в мемо
               MyMsg.lParam:= NewString(ErrMsg);
               SendMessage(FrmMain.Handle, WM_GETFORSPLASHSTR_MSG, 0, MyMsg.LParam);

               i:= 10;//счетчик на 10 циклов

               //немного заморозим отрисовку на(i) циклов, чтобы юзер смог осмыслить сообщение об ошибке,
               //пока не окончился таймер или не прилетело сообщение из сплеша, что там нажата кнопка 'Esc'
               while (i > 0) and (not FrmMain.FIsFinishedThread) do
               begin
                 Dec(i);
                 {$IFDEF UNIX}
                   MyMsg.LParam:= NewString(Format('Закрыть (%d)',[i]));
                   MyMsg.WParam:= 1; //нажатие левой кнопки с обратным отсчетом завершит поток
                   SendMessage(FrmMain.Handle, WM_GETFORBTNRIGHT_MSG, MyMsg.WParam, MyMsg.LParam);

                   MyMsg.LParam:= NewString('Сохранить в буфер обмена');
                   MyMsg.WParam:= 2; //нажатие правой кнопки сохранит текст ошибки в буфер обмена и завершит поток
                   SendMessage(FrmMain.Handle, WM_GETFORBTNLEFT_MSG, MyMsg.WParam, MyMsg.LParam);
                 {$ELSE}
                   MyMsg.LParam:= NewString(Format('Закрыть (%d)',[i]));
                   MyMsg.WParam:= 1; //нажатие левой кнопки с обратным отсчетом завершит поток
                   SendMessage(FrmMain.Handle, WM_GETFORBTNLEFT_MSG, MyMsg.WParam, MyMsg.LParam);

                   MyMsg.LParam:= NewString('Сохранить в буфер обмена');
                   MyMsg.WParam:= 2; //нажатие правой кнопки сохранит текст ошибки в буфер обмена и завершит поток
                   SendMessage(FrmMain.Handle, WM_GETFORBTNRIGHT_MSG, MyMsg.WParam, MyMsg.LParam);
                 {$ENDIF}

                 Sleep(1000);
               end;

               FrmMain.FIsFinishedThread:= True;//сообщим сплешу, что поток закончился и можно закрыться
               Exit;//переходим к секции finally
             end; {on E:EIBError do}
        end; {коннект к базе данных}

        try {коннект к таблице с настроками пользователя}
          with FrmMain do
          begin {with FrmMain do}
            MyMsg.LParam:= NewString('Загружаем или создаем настройки пользователя');
            SendMessage(Handle, WM_GETFORSPLASHSTR_MSG, 0, MyMsg.lParam);

            Sleep(1000);

            //проверяем, есть ли у этого юзера запись в таблице настроек
            QrySettings.SQL.Text:=
            'SELECT COUNT (RDB$DB_KEY) AS cnt FROM RDB$DOCSETTINGS WHERE NAME = UPPER(:prmUsrName)';
            QrySettings.Prepare;
            QrySettings.ParamByName('prmUsrName').Value:= FUsrNm;
            QrySettings.Open;

            //если нет, то создаем запись с его именем и дефолтовыми настройками
             if QrySettings.FieldByName('cnt').AsInteger = 0 then
             begin
               TransWrite_main.StartTransaction;
               try {try .. except попытка записи в таблю настроек}
                 ExecSql_Settings.SQL.Text:= 'EXECUTE PROCEDURE CREATE_DOCSETTINGS_NEW_USER (:prmNAME,:prmNOTE)';
                 ExecSql_Settings.Params.ByName('prmNAME').Value:= LowerCase(UsrNm);
                 ExecSql_Settings.Params.ByName('prmNOTE').Value:= '';
                 ExecSql_Settings.ExecQuery;
                 TransWrite_main.Commit;
               except {try .. except попытка записи в таблю настроек}
                 TransWrite_main.Rollback;
                 FCurrentUser:= 'DEFAULT_USER';//текущий юзер для загрузки настроек

                 // далее поскипал однотипный код
				 
                 //если нажали кнопку 'Нет' на сплэше, то переходим в блок finally и прерываем коннект
                 if FIsFinishedThread then Exit;
               end; {try .. except попытка записи в таблю настроек}
             end;
          end; {with FrmMain do}
        except {коннект к таблице с настроками пользователя}
          FrmMain.FCurrentUser:= 'DEFAULT_USER'; //текущий юзер для загрузки настроек
          // далее поскипал
          
          //если нажали кнопку 'Прервать' на сплэше, то переходим в блок finally и прерываем коннект
          if FrmMain.FIsFinishedThread then Exit;
        end; {коннект к таблице с настроками пользователя}


      {TODO: отладить настройки юзера}

        //грузим настройки юзера
        //FrmMain.LoadAppSettings;


        try {коннект к остальным данным}

          //коннектимся к таблице
          MyMsg.LParam:= NewString('Получаем данные');
          SendMessage(FrmMain.Handle, WM_GETFORSPLASHSTR_MSG, 0, MyMsg.LParam);

          //спрячем левую кнопку на сплэше, передав туда "нулевой" признак видимости
          MyMsg.WParam:= 0;
          MyMsg.LParam:= NewString('');
          SendMessage(FrmMain.Handle, WM_GETFORBTNLEFT_MSG, MyMsg.WParam, MyMsg.LParam);

          //текст для правой кнопки
          MyMsg.LParam:= NewString('Прервать');
          MyMsg.WParam:= 1;
          SendMessage (FrmMain.Handle, WM_GETFORBTNRIGHT_MSG, MyMsg.WParam, MyMsg.LParam);

          Sleep(1000);

          FrmMain.QrySelect.Active:= True;
        except {коннект к остальным данным}
         on E:EIBError do
           begin
             //текст ошибки
             {$IFDEF UNIX} ErrMsg:= E.Message; {$ELSE} ErrMsg:= WinCPToUTF8(E.Message); {$ENDIF}

             // далее поскипал однотипный код
             FrmMain.FIsFinishedThread:= True;//сообщим сплешу, что поток закончился и можно закрыться
             Exit;//переходим к блоку код в finally
           end;
        end; {коннект к остальным данным}


      finally {цикл коннекта к базе и проверок}
        //если ранее взвели флаг окончания потока
        if FrmMain.FIsFinishedThread
          then //то прервем коннект
            begin
              FrmMain.DBase_main.Connected:= False;
            end
          else //иначе доведем дело до конца
            begin
              //если коннект успешный, применяем загруженные настройки
              if FrmMain.DBase_main.Connected then FrmMain.SetAppSettings;

              //взведем флажок (чтобы сплэш знал о завершении потока и дал себя закрыть)
              FrmMain.FIsFinishedThread:= True;
            end;

        //закроем сплэш
        SendMessage(FrmMain.Handle,WM_CLOSESPLASHFORM_MSG,0,0);
      end; {цикл коннекта к базе и проверок} {mttConnectDB:}

{======================================================================================}
    mttDisconnectDB: ;

{======================================================================================}
    mttOpenDSet: ;

  end; {case FThreadTarget of}


end;    

создаю и запускаю поток
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
procedure TFrmMain.ActOpenDBExecute(Sender: TObject);
begin
  if Assigned(FConnectThread) then Exit;//если поток все еще крутится, выйдем отседова

  FCurrentUser:= UsrNm;//запоминаем залогинившегося юзера

  //создаем приостановленный поток
  FConnectThread:= TMyThread.Create(True);

  try
    //определяем, какая часть потока бцдет реализована
    FConnectThread.FThreadTarget:= mttConnectDB;

    //передаем параметры коннекта в фоновый поток
    with FConnectThread do
      begin
        FChrSet:= ChrSet;
        FDbName:= DBName;
        FLibName:= LibName;
        FUsrNm:= UsrNm;
        FPW:= PW;
        FUsrRole:= UsrRole;
      end;

    //создаем сплэш
    SplashForm:= TFrmSplash.Create(Application);

    //стартуем ожидающий поток
    FConnectThread.Start;
    try
      SplashForm.ShowModal;//показываем сплэш
    finally
      FreeAndNil(SplashForm);
    end;
  finally
    FreeAndNil(FConnectThread);
  end; 



В результате, на никсах, видно подтормаживание анимации, и через раз лезет окно с ошибкой (обычно в конце цикла коннекта)
Код: pascal
1.
2.
3.
Проект <тут название моего проекта> вызвал класс исключения 'External: SIGABRT'.

 По адресу B7FDCD40


В окне ассемблера
Код: pascal
1.
B7FDCD40 5d                       pop    %ebp


при попытке войти отладчиком в процедуру получаю
Код: pascal
1.
00000000 ??????


В файле проекта вроде все должно быть корректно
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
program andrology_pr;

{$mode objfpc}
{$H+}
{$codepage UTF8}

uses
  {$IFDEF UNIX}
  cthreads
  , cmem
  ,
  {$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, rxnew, ibexpress, main_u, main_functions_u, splash_u, variable_u,
  dm_pict_u;

{$R *.res}

begin
  Application.Scaled:=True;
  Application.Title:='<название проекта>';
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TDM_pictures, DM_pictures);
  Application.CreateForm(TFrmMain, FrmMain);
  Application.Run;
end.



ps. У меня ощущение, что приложению оперативки не хватает (Деб крутится на виртуалке с RAM 2048 kB). пробовал выделить ей 4 гига, картина та же
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457263
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокВ окне ассемблера
Код: pascal
1.
B7FDCD40 5d                       pop    %ebp


А выше что? Похоже, что перед выходом из некой процедуры стэк ломаный, возможно обращение к (уже) несуществующему объекту.
Док
Код: pascal
1.
if FrmMain.DBase_main.Connected then FrmMain.SetAppSettings;


Тут нет обращения к визуальной части?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457291
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. в отладке может что-то видно?
2. в основном потоке код работает?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457306
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

отладчик в Лазаре никакущий, в потоке вообще отладить что-либо сложно, если только пользовать DebugLn.

Как назло, решил переставить новую ревизию (в предыдущей че-та с настройками случилось - не сохраняются). Теперь не компилится с ошибкой "...lazarus_trunk\ide\sourcefilemanager.pas(6459,27) Error: (5038) identifier idents no member "DesignPPI"". Ужос!!!


зы. щас, разберусь со средой, отвечу :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457343
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanТут нет обращения к визуальной части?
Есть, и еще какое.
примерно так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
procedure TFrmMain.SetAppSettings;
begin
//определяем доступность грида в зависимости от состояния коннекта
Grid_main.Enabled:= DBase_main.Connected;

//настройки сетки
with Grid_main do
  begin
    if Enabled
      then
        begin
          TitleFont.Color:= clDefault;
        end
      else
        begin
          TitleFont.Color:= clGrayText;
        end;
  end;


//и далее в том же духе

// для отладки
if FrmMain.DBase_main.Connected
  then FrmMain.Label4.Caption:= 'connected'
  else FrmMain.Label4.Caption:= 'not connected';
end;

...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457365
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокЕсть, и еще какое.
Дак нельзя так делать.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457460
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanДак нельзя так делать.
а если загрузка настроек из табли длительная, то как быть. В следующем потоке делать?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457473
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокwadmanДак нельзя так делать.
а если загрузка настроек из табли длительная, то как быть. В следующем потоке делать?
Суть не в этом, а в том, что сообщения (строками) для формы кидаешь-же сообщениями, что верно.
Так и это (применение настроек) нужно делать подобным образом.

Яж потому и спрашивал, как форма узнает, что поток отработал?
Тут же получается, что поток работает с базой параллельно с формой...
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457474
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дока если загрузка настроек из табли длительная, то как быть.Загрузить в буфер, отдать буфер основному потоку и там применить
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457486
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Загрузить в буфер, отдать буфер основному потоку и там применить
а как это технически выглядит, можно хотя бы схематично?
wadmanТут же получается, что поток работает с базой параллельно с формой...
хм.... а я и не подумал.

Т.е., мне теперь в потоке каждый параметр вычитывать из табли и перегонять по одному сообщению в основную форму что ли? А нельзя их как-то массивом передать?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457493
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокА нельзя их как-то массивом передать?
Хоть через TStringList (это один вариантов "буфера", что предложил _Vasilisk_).
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457527
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
закомментил
Код: pascal
1.
if FrmMain.DBase_main.Connected then FrmMain.SetAppSettings;


вроде валиться перестала. Щас буду думать, как параметры передавать: столбиком или в строчку :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457528
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

кстати, а какова максимальная длина строки, которую можно через NewString передать?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457536
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доккстати, а какова максимальная длина строки, которую можно через NewString передать?
С моей стороны нет ограничений, все на уровне ОС/языка по свободной памяти и строкам.
http://wiki.freepascal.org/Character_and_string_types#AnsiString тут и ниже.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457557
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

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

авторВряд-ли, т.к. поток не компонент. Его не указать владельцем (чтоб он всех своих за собой "забрал").

можно компонентную обёртку всунуть вместо чистого потока.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457565
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_2. Если несколько потоков создают коннекты, то эта процедура должна быть синхронизирована единым мьютексом
3. Пункт 2 распространяется на весь процесс. И если коннекты создаются в разных dll, то также должен использоваться единый мьютекс
Если я не ошибаюсь, то такая особенность (необходимость синхронизации вызова isc_attach_database, т.е. TIBDatabase.Connected := True) была (что касается Firebird) до версии 3.0. А сейчас уже исправили (в fbclient.dll/so) это дело.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457573
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonможно компонентную обёртку всунуть вместо чистого потока.
Уже предлагал много раз. :( ладно хоть не на асме клепает.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457593
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockбыла (что касается Firebird) до версии 3.0.Правильно. А в Interbase осталась. С чем работает Док и каких версий - неизвестно
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457602
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_С чем работает Док и каких версий - неизвестно
Загляни в его подпись 20500242
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457642
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanУже предлагал много раз. :( ладно хоть не на асме клепает.
нафиг, всегда проще понять и найти ошибку там, годе написал код сам :)

_Vasilisk_1. С одним коннектом может работать только один поток
2. Если несколько потоков создают коннекты, то эта процедура должна быть синхронизирована единым мьютексом
как-то был разговор про потокобезопасность FB, подробностей не вспомню. Поэтому хотел уточнить, в общих случаях:
1. если я в доп.потоке хочу что-то сделать с таблей (неважно, в основном потоке с ней что-то происходит или нет), мне нужно создать новый коннект?
2. если я хочу с одной и той же таблей сделать что-то (пусть пока будут селекты) из 2 и более параллельных коннектов, мне так же нужно будет создавать новый коннект на каждый поток, чтобы избежать использование мьютексов?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457649
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док1. если я в доп.потоке хочу что-то сделать с таблей (неважно, в основном потоке с ней что-то происходит или нет), мне нужно создать новый коннект?Да
Док2. если я хочу с одной и той же таблей сделать что-то (пусть пока будут селекты) из 2 и более параллельных коннектов , мне так же нужно будет создавать новый коннект на каждый поток , чтобы избежать использование мьютексов?Я не понял. У тебя два соединения. Какой еще новый коннект на поток?

Два простых правила:
1) Каждый поток работает со своим коннектом.
2) До FB 3.0 создание нового коннекта должно было быть синхронизировано

Первое правило можно иногда нарушать. Но когда именно - не знаю :)) Потому лучше не нарушать
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457652
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Насколько я знаю, нельзя одновременно доступаться из разных потоков к коннекту и наборам. Последовательно - можно.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457657
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon_Vasilisk_,

Насколько я знаю, нельзя одновременно доступаться из разных потоков к коннекту и наборам. Последовательно - можно.
В тройке вроде уже и одновременно можно*, но только это бессмысленно - там просто сработает внутренний объект синхронизации работы на коннекшен, если не ошибаюсь, т.ч. будет всё равно последовательно, в лучшем случае.

*Имеется ввиду работа с ISC-API. Объекты же "компонентов" юзать одновременно в разных потоках нельзя в любом случае по другим причинам.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457659
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док> Поэтому хотел уточнить, в общих случаях:

C т.з. FB (2.5 и выше) можешь делать что хочешь
(коннекты и вызовы), где хочешь (хоть в основном,
хоть в доп.потоках) и как хочешь (в любом порядке).
Думать нужно лишь о VCL-ной части - чтобы датасеты
смогли поделить транзакции и коннекты.

_Vasilisk_> Два простых правила:

Ну уж тебе-то стыдно должно быть. :)

_Vasilisk_> 2) До FB 3.0

До 2.5. В 3.0 на сей счёт ничего не менялось, вроде.
Впрочем, могу и ошибаться.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457714
_Vasilisk_Два простых правила:

1) Каждый поток работает со своим коннектом.
2) До FB 3.0 создание нового коннекта должно было быть синхронизировано

Первое правило можно иногда нарушать. Но когда именно - не знаю :)) Потому лучше не нарушать
Хм. Получается, я давненько по минному полю гуляю... Не, то есть про коннект на поток - это я знал и делал.
А вот про синхронизацию че-та ни сном ни духом. Если не трудно, подскажи, как это делать?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457746
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Викторович_Если не трудно, подскажи, как это делать?
Сделай отдельный поток только для открытия коннектов. Например, через те же сообщения.
Либо открывай в основном потоке, а для дальнейшей работы - отдавай в другой.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457749
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамДо 2.5. В 3.0 на сей счёт ничего не менялось, вроде.
Впрочем, могу и ошибаться.

http://www.ibase.ru/ibx/#onlogin чуть ниже описано про подключение в многопоточке.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457752
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Викторович_А вот про синхронизацию че-та ни сном ни духом.
Аналогично... Ни разу не было и менять не буду. :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457755
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanчуть ниже описано про подключение в многопоточке
получается, чисто коннект к базе лучше выносить в отдельный поток? Особенно, если таймаут коннекта занимает более 1 мин?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457757
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докwadmanчуть ниже описано про подключение в многопоточке
получается, чисто коннект к базе лучше выносить в отдельный поток? Особенно, если таймаут коннекта занимает более 1 мин?
Насколько я понял, эта бага всплывает, когда в программе более одного коннекта, т.к. создание подключения не синхронизировано в нутрях клиента.
У меня всегда один коннект был, не было подобных проблем ни разу.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457816
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докwadmanчуть ниже описано про подключение в многопоточке
получается, чисто коннект к базе лучше выносить в отдельный поток? Особенно, если таймаут коннекта занимает более 1 мин?
Не знаю, зачем на ibase.ru придумали эту супер-идею с очередью в отдельном потоке для установления коннекшенов, я в таких случаях поступал так:
Код: pascal
1.
2.
3.
4.
5.
6.
EnterCriticalSection( DB_CONNECT_CS );
try
  db.Connected := True;
finally
  LeaveCriticalSection( DB_CONNECT_CS );
end;


пока это было актуально. А это действительно было актуально - я напарывался.

Сейчас, к счастью, НАКОНЕЦ-ТО, я уже поубирал во многих местах эти ужасающие синхронизации на такой долгой операции, как коннект.
Вообще, это был ужас. Просто нереальный. Заставлять коннектиться последовательно.

Тебе не надо ничего такого, каз у тебя FB3.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457817
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockТебе не надо ничего такого, каз у тебя FB3.
Да, тут очень важно, чтобы у тебя и клиент был (fbclient/gds32) от FB3.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39457819
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Викторович_Хм. Получается, я давненько по минному полю гуляю... Не, то есть про коннект на поток - это я знал и делал.
А вот про синхронизацию че-та ни сном ни духом.
Везло. Мне тоже долго везло, а потом резко перестало.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458192
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman> http://www.ibase.ru/ibx/#onlogin
wadman> чуть ниже описано про подключение в многопоточке.

То ли я не увидел, то ли там ничего про версии FB и многопоток.
Все проблемы, которые есть - это в датасетах/потоках запутаться
или сделать "однопоточный многопоток".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458200
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамТо ли я не увидел, то ли там ничего про версии FB и многопоток.
Нужной закладки на странице нет, потому ссылка на ближайшую.
Про версии ничего нет, но текст там такой:

ibase.ruИногда при подсоединении к БД в созданном thread может возникнуть ошибка на вызове isc_attach_database (собственно на функции, которая и осуществляет соединение к БД при вызове IBDatatase.Connected:=True). В этом случае вынесите открытие соединения в главный thread приложения, а дальнейшие операции с коннектом производите в пределах нужного thread.

Судя по дате последнего изменения 09.2014 - речь о версиях до тройки.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458279
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть некоторые сомнения в достоверности этого текста.
Лучше таки уточнить, и пусть Дима исправляет, актуализирует
и уточняет, если что.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458285
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамЛучше таки уточнить, и пусть Дима исправляет, актуализирует
и уточняет, если что.
наверное, имеет смысл кому-то компетентному (а то ото всех только и слышишь: вроде бы, вроде бы ....) поднять тред, связанный с его сайтом тут, в дельфевой ветке.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458354
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док> ото всех только и слышишь: вроде бы, вроде бы

Дык это стандартная оговорка, даже от птицеводов -
"не должно вроде бы". Начиная с 2.5 синхронизация
делается на уровне порта (т.е. библиотеки), поэтому
проблем "быть не должно вроде бы". А Дима, может,
на что-то наткнулся, либо этот текст висит лет 10 не
исправленный (версии и разница между IB/FB там
вообще не упомянуты).

> поднять тред, связанный с его сайтом тут, в дельфевой ветке.

Не вижу большого смысла. В соседнем разделе где-то
был, но в основном ему указывают об ошибках и пр.
где попало (где речь зайдёт или где обнаружат).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458593
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если получение данных с ФБ идет в одном потоке, а работа с этими данными и/или их визуализация - в другом, возникает следующий вопрос: Откуда взялась уверенность, что компоненты доступа к БД сделаны safe-thread и корректно реализуют "проход" данных сквозь барьер кэша ядра процессора? Надо заглянуть в исходники компонент доступа к БД и убедится в использовании ими команд процессора инвалидации кэшей для ядер процессора, кэширующих область памяти с полученными от ФБ данными.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458735
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devОткуда взялась уверенность
Из всей ветки я сделал для себя вывод: хочешь что-то делать с данными в доп.потоке, создай в нем коннект - измени данные - убей коннект. Т.е., реализуй логику приложения так, как будто это доп.поток = новый юзер.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458744
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док, с потоконебезопасными компонентами только так. Конечно, есть вариант с полной синхронизацией - инвалидацией всего кэша, но это пагубно сказывается на производительности. Не знаю как в Lazarus, но, к примеру, у компонента Borland/Embarcadero TThread есть метод Synchronize().
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458796
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devу компонента Borland/Embarcadero TThread есть метод Synchronize().
, который вообщеиспользовать нельзя категорически, т.к. он как минимум:
1) замораживает очередь сообщений vcl-потока до обработки всех методов, вызванных в Synchronize во всех потоках;
2) Может приводит к существенной (неизвестно, какой, возможно и бесконечной - зависит от обработчика сообщения, находящегося в очереди) задержке перед вызовом метода, но это ладно;
3) может вообще не вызваться, что приведет ко многим интересным последствиям, любое из которых - полный крах всей логики приложения.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458816
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, который вообщеиспользовать нельзя категорически, т.к. он как минимум:
1) замораживает очередь сообщений vcl-потока до обработки всех методов, вызванных в Synchronize во всех потоках;
2) Может приводит к существенной (неизвестно, какой, возможно и бесконечной - зависит от обработчика сообщения, находящегося в очереди) задержке перед вызовом метода, но это ладно;
3) может вообще не вызваться, что приведет ко многим интересным последствиям, любое из которых - полный крах всей логики приложения.Пункт 1, это преодоление барьера конвеера команд ядра процессора, необходимое для реализации полной синхронизации.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458820
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devПункт 1, это преодоление барьера конвеера команд ядра процессора, необходимое для реализации полной синхронизации.
Ну отлично. Преодолевайте, кому хочется. Мне ни разу в жизни не понадобилось видимо "преодолевать барьер конвеера".
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458846
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458873
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev http://lxr.linux.no/linux v2.6.36/Documentation/memory-barriers.txt
http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf
Эти ссылки имеют к TThread.Synchronize, а тем более к теме топика, такое же отношение, как послезавтрашний футбольный матч Шахтёр-Динамо к выборам президента Сербии.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39458967
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, эти ссылки я привел для общего понимания процесса. В своей реализации метод Synchronize использует мьютексы и критические секции, которые, в свою очередь, используют реализацию барьеров памяти. К примеру, на MSDN явно указано:

The following synchronization functions use the appropriate barriers to ensure memory ordering:
Functions that enter or leave critical sections
Functions that signal synchronization objects
Wait functions
Interlocked functions
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39459013
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,

Для "общего понимания процесса", которое тут и так у всех было и есть, в т.ч. у ТС, достаточно понятия "синхронная работа с ресурсом", где "синхронная" - означает невозможность чтения и записи в ресурс одновременно в более, чем одном потоке.
Какими средствами достигается подобная синхронность - с помощью логики приложения и/или
Functions that enter or leave critical sections
Functions that signal synchronization objects
Wait functions
Interlocked functions
, вообще не важно в данном случае. Еще менее важно, чем высокие понятия типа "барьера конвеЙера".

Я вообще зря вклинился в топик, увидев совет использовать TThread.Synchronize. Для меня это красная тряпка, каюсь.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39459030
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockЯ вообще зря вклинился в топик, увидев совет использовать TThread.Synchronize. Для меня это красная тряпка, каюсь.Негативный опыт? :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39459068
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devYuRockЯ вообще зря вклинился в топик, увидев совет использовать TThread.Synchronize. Для меня это красная тряпка, каюсь.Негативный опыт? :)
Немного очень давно, но скорее невозможность позитивного. Как, например, и в галочке "Auto create forms", установленной по умолчанию.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39459412
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockЕще менее важно, чем высокие понятия типа "барьера конвеЙера".В общем-то, я не совсем корректно употребил словосочетание "барьер конвейера", так как само понятие "барьера памяти" при выполнении таких команд процессора, как mfence, sfence и lfence подразумевает полное завершение всех предыдущих команд процессора работы с памятью, включая сброс информации из кэша в память и не допуская начала выполнения новых до момента, пока не будет пройден "барьер".
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600968
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Апну ветку, чтобы не плодить новую.

На форме в ГУИ лежит мемори-датасет (RDM), который надо заполнить в доп.потоке выборкой из базы.

Пока сделал так: создал в потоке коннект, в созданный там же датасет забрал данные из БД и там же в доп.потоке заполнил значениями гуишный RDM.

Насколько это потокобезопасно? Как реальные поцоны это делают по феншую?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600978
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокКак реальные поцоны это делают по феншую?
Не знаю, как посоны, но я-бы на момент заполнения датасета отключил-бы его от визуальной части (datasource.dataset = nil) и подключил-бы только в основном потоке по факту заполнения.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600979
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

в принципе, я так и сделал
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure TFrmMain.btnAddClick(Sender: TObject);
begin
  FMyThread := TMyThread.Create(True);
  try
    RMD.DisableControls;

    FrmSplash := TFrmSplash.Create(Application);
    FMyThread.Start;
    try
      FrmSplash.ShowModal;
    finally
      FreeAndNil(FrmSplash);
    end;
  finally
    RMD.EnableControls;
    FreeAndNil(FMyThread);
  end;
end;


а в остальном все верно?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600983
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дока в остальном все верно?
Не, ты не так сделал. Просто отключил "управление", что не мешает гриду обращаться к датасету в основном потоке.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600984
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

ок, учту. Спасибо.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39600992
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вопрос. Скажем, табля в базе содержит несколько десятков килозаписей. Чтобы не тащить все на клиента (в датасете FetchAll = False), я запросом (в доп.потоке) забираю первые 100-200, примерно так:
Код: pascal
1.
2.
3.
SELECT FIRST 200 *
FROM TBL_TEST
ORDER BY 1 


При прокрутке в гриде мне нужно получить следующую порцию для отображения. Как это сделать технически?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601000
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокКак это сделать технически?
Хранить счетчик загруженных строк и на момент достижения нижней границы грузить фоном следующие N записей. Плюс добавить флаг, что все данные выбраны, чтоб лишний раз не дергать запрос.
См. SELECT FIRST SKIP https://firebirdsql.org/refdocs/langrefupd20-select.html
Отцеплять datasource или нет (или выключать грид) - решай сам, по тестированию.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601001
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя, может FB сам фетчит по одной записи? Тогда в потоке особой нужды нет.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601003
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanХотя, может FB сам фетчит по одной записи? Тогда в потоке особой нужды нет.
А, я забыл, что ты данные в памяти держишь. :)
Тогда как выше описал.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601013
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

грид сам разве не заберет? или нужно забирать в доп. потоке?

авторсоздал в потоке коннект

Насколько я знаю - можно создавать в любом потоке. Только что доступаться потом можно только из одного одновременно. То есть - не обязательно его именно в доп. потоке создавать.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601059
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

в доп.потоке только для меморидатасета. В принципе можно для этого случая и все записи фетчить (в основном у меня это справочники).

А вот если открывать обычный датасет с парой десятков тыс.записей в основном потоке (да еще и со всякими многоэтажными джойнами внутри), то гуи заметно лагает. Потому и задался вопросом: сразу грузить все, но в доп.потоке, или подгрузить сначала в основном пару сотен. Вот дальше не помню, грид, используя этот же запрос с select first, сам подгрузит следующую сотню или это надо делать принудительно :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601061
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanХотя, может FB сам фетчит по одной записи? Тогда в потоке особой нужды нет.
Помнится, недавно был разговор за полноценный сервер, что он пачками отдает записи. Вот для эмбеддед да, каждый раз будет отдаваться по одной записи, если я правильно понял. Наверно в этом случае лаги будут?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601085
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокВот дальше не помню, грид, используя этот же запрос с select first, сам подгрузит следующую сотню или это надо делать принудительно :)
Как он подгрузит, если запрос возвращает те строки, которые ограничены first и больше быть не должно?
Грузить "руками" и порциями это как раз для мемдатасета.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39601259
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanКак он подгрузит, если запрос возвращает те строки, которые ограничены first и больше быть не должно?
Логично.
У RxDBGrid есть фишка фетчить помещающиеся на экране записи. Надо будет поэкспериментировать и так, и сяк.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39603378
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanХранить счетчик загруженных строк и на момент достижения нижней границы грузить фоном следующие N записей.
Вот тут загвоздка. Где отслеживать условие BOF или EOF датасета? Пробовал в OnDataChange датасорса,
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
procedure TFrmMain.DSDataChange(Sender: TObject; Field: TField);
begin
  if Qry.Active then
  begin
    if Qry.EOF then
    begin
      FprmFrom:= FprmTo + 1;
      FprmTo:= FprmFrom + RecInterval;

      //if (Qry.RecordCount - FprmFrom) < RecInterval then
      //begin
      //  FprmFrom:= Qry.RecordCount - RecInterval;
      //  FprmTo:= Qry.RecordCount;
      //end;

    end;

    if Qry.BOF then
    begin
      FprmTo:= FprmFrom - 1;
      FprmFrom:= FprmTo - RecInterval;

      if FprmFrom < 1 then
      begin
        FprmFrom:= 1;
        FprmTo:= FprmFrom + RecInterval;
      end;

    end;
    btnAddClick(Sender);//фетч датасета с параметрами в доп.потоке
  end;
end;


но событие срабатывает при первом же подключении к датасету с зацикливанием фетча записей до полной выборки
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39604406
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужики, кто как делает, посоветуйте.

Размер выборки ограничивается параметрами FIRST/SKIP (FB3). SKIP увеличивается/уменьшается соответственно тому, куда скроллится грид. Наступает момент, когда SKIP превышает число записей в таблице БД (датасет при этом IsEmpty).

Хотел спросить, как проконтроллировать возврат пустого датасета? завести в доп.потоке еще один датасет (тогда лишний коннект при каждой новой порции фетча)?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605257
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коннекта и одного хватит для фоновых задач. У тебя алгоритм сейчас какой?
Я-бы фоном фетчил по 200 записей и возвращал их основному потоку, а в нем-бы заливал в мемори датасет.
Переброска в памяти дело шустрое, едва заметное. А при пустом результате просто выставлял-бы флаг, что данных больше нет. Хотя... Если база многопользовательская, то данные могут и появиться.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605283
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanЯ-бы фоном фетчил по 200 записей и возвращал их основному потоку, а в нем-бы заливал в мемори датасет.
Я в ходе эспериментов тоже пришел к выводу, что создавать коннект и фетчить записи нужно в доп.потоке, а данные заливать в память. Смущает, что при каждом фетче создается-уничтожается коннект: тру-программисты так делают или нет? :)

Основной затык у меня пока в динамическом увеличении/уменьшении SKIP(n) в условной конструкции 'SELECT FIRST 200 SKIP(n) ...' при достижении начала (BOF) или конца(EOF) резалтсета (чтобы увеличить/уменьшить SKIP на FIRST-ное количество записей). Вернее, где проводить эту проверку. В идеале повесить бы эту проверку в OnDataChange датасорса, но там происходит зацикливание, как только динамически подключаешь его к датасету
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  try
    DBGrid.BeginUpdate;
    DS.DataSet:= nil;
    try
      FMyThread := TMyThread.Create(True,FetchInterval,FprmSkip);
      try
        SplashForm := TFrmSplash.Create(Application);
        FMyThread.Start;
        SplashForm.ShowModal;
      finally
        FreeAndNil(SplashForm);
      end;
    finally
      FreeAndNil(FMyThread);
    end;
  finally
    DS.DataSet:= Qry;//подключаем вот тут
    DBGrid.EndUpdate(True);
  end;


Потому и вопрошал, кто где и как делает.

зы. Кстати, тут интересная дискуссия развернулась по отрисовке LCL-элементов во время работы потоков.

Также кем-то была высказана мысль, что для передачи строк в основной поток недопустимо использовать PostMessage, т.к. указатели на них могут "уже потеряться", пока до них доберется основной поток. Принципиальных возражений вроде нет, но ... я заметил, что Линукс элементарно "висит" пока не заменишь SendMessage на PostMessage
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605300
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокВернее, где проводить эту проверку.
Чем AfterScroll не подошёл?
Я вообще-бы не делал серфинг вперед-назад, а сделал-бы просто подгрузку в одном направлении -> вперед.
Докзы. Кстати, тут интересная дискуссия развернулась по отрисовке LCL-элементов во время работы потоков.

Также кем-то была высказана мысль, что для передачи строк в основной поток недопустимо использовать PostMessage, т.к. указатели на них могут "уже потеряться", пока до них доберется основной поток. Принципиальных возражений вроде нет, но ... я заметил, что Линукс элементарно "висит" пока не заменишь SendMessage на PostMessage
Я давно прошел эти этапы. :) Все через сообщения (в т.ч. и строки через выделенную память) и никаких проблем.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605364
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanЯ вообще-бы не делал серфинг вперед-назад, а сделал-бы просто подгрузку в одном направлении -> вперед.
хм, а это мне в голову как-то сразу не пришло :) А датасет в памяти сможет 400К записей и больше удержать?

wadmanВсе через сообщения (в т.ч. и строки через выделенную память) и никаких проблем.
вот в этом-то вся и беда, надо выделять/освобождать память для передаваемых объектов - геморройно :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605370
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокА датасет в памяти сможет 400К записей и больше удержать?
Сначала спроси у человека, сможет ли он хотя-бы тысячу записей удержать в голове.
Не сталкивался с такими потребностями... Тут только тестировать, размер строки бывает разным.
Докнадо выделять/освобождать память для передаваемых объектов - геморройно :)
Ты же это не сам будешь делать, а напишешь для этого код, который работает за тебя. :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605371
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докдля передачи строк в основной поток недопустимо использовать PostMessage,Допустимо, но с умом
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var
  Str: string;
begin
  Str := 'fffff';
  PostMessage(Handle, WM_MSG, WPARAM(Str), 0);
  Pointer(Str) := nil;  // "Потеряли" ссылку на строку
end;

procedure WMMsg(var AMsg: TMessage);
var
  str: String;
begin
  Str := '';  // Если переменная до этого была инициализирована, то финализируем ее
  WPARAM(str) := AMsg.wParam;  // Присваиваем указатель без манипуляции со счетчиком ссылок
  ShowMessage(Str);
  // Тут строка 'fffff', наконец, уничтожится
end;
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605375
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокА датасет в памяти сможет 400К записей и больше удержать?Однонаправленный сможет
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605543
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Докдля передачи строк в основной поток недопустимо использовать PostMessage,Допустимо, но с умом
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var
  Str: string;
begin
  Str := 'fffff';
  PostMessage(Handle, WM_MSG, WPARAM(Str), 0);
  Pointer(Str) := nil;  // "Потеряли" ссылку на строку
end;

procedure WMMsg(var AMsg: TMessage);
var
  str: String;
begin
  Str := '';  // Если переменная до этого была инициализирована, то финализируем ее
  WPARAM(str) := AMsg.wParam;  // Присваиваем указатель без манипуляции со счетчиком ссылок
  ShowMessage(Str);
  // Тут строка 'fffff', наконец, уничтожится
end;


Классный вариант! Правда, хак. Я у себя делал через NewStr/DisposeStr.
Кстати, надо еще помнить, что PostMessage может вернуть False и не отправить сообщение. То бишь в данном варианте
Код: pascal
1.
2.
  if PostMessage(Handle, WM_MSG, WPARAM(Str), 0) then
    Pointer(Str) := nil;  // "Потеряли" ссылку на строку
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605558
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий №2Правда, хак.Не хак. Просто понимание работы счетчика ссылок
Василий №2Я у себя делал через NewStr/DisposeStr.Это лучше.
Василий №2PostMessage может вернуть False и не отправить сообщение.Хорошее уточнение

Главный недостаток обоих способов, что для Send тоже нужно дополнительно выделять память
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605575
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Это лучше.

обязательным копированием содержимого строки?

лучше просто очередь завести и в нее сбрасывать
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605589
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochобязательным копированием содержимого строки?Читабельнее
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605658
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

TThreadQueue.Enqueue еще читабельнее
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605752
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий №2Кстати, надо еще помнить, что PostMessage может вернуть False и не отправить сообщение. То бишь в данном варианте
Код: pascal
1.
2.
  if PostMessage(Handle, WM_MSG, WPARAM(Str), 0) then
    Pointer(Str) := nil;  // "Потеряли" ссылку на строку


Пофиг. Я PostMessage использую только в некритичных случаях (в гуи инфу отослать для отображения) и то, только под линукс (он, собака, просто перестает рисовать окна, если завалить его потоком SendMessage). Для остальных случаях - только SendMessage
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605774
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокПофиг. Я PostMessage использую только в некритичных случаяхНе пофиг. Будет утечка памяти если не проверить результат и тупо обнулить
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605845
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

ок, возьму на заметку. Спасибо за пояснения
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39605983
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Не хак. Просто понимание работы счетчика ссылок
Не... таки хак. Ибо вмешательство во внутренний механизм.
_Vasilisk_Главный недостаток обоих способов, что для Send тоже нужно дополнительно выделять память
Хм. Занафига? Ведь пока Send не отработает, он не вернет управление, а значит, и строка не уничтожится
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606126
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Не пофиг. Будет утечка памяти если не проверить результат и тупо обнулить

Это ее не устранит. Хотя вероятность понизит. Но устранит только гарантия "сообщение получено, за освобождение памяти теперь отвечает другой блок программы"

А "если проверить результат" - то ты просто передал какое-то сообщение Windows, не свеой программЕ, а операционке.

А оно было доставлено до нужного места программы? Может окошко раньше получило WM_CLOSE и закрылось ? Или даже не окно, а весь поток повис и был отстрелен? Или ReCreateWND случился и хэндл поменялся? Или это просто было не то окно, перепутали хэндл, и оно в принципе такие мэссиджи не умеет обрабатывать ?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606129
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокДля остальных случаях - только SendMessage

Если всё это в рамках одной программы - то SendMessage хорош только для однородности с PostMessage, чтобы одно в другое превращать заменой 4-х символов.
А в рамках VCL (и наверное LCL) вместo SendMessage есть TWinControl.Perform
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606153
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

я бы уж тогда лучше предпочел Queue(безопасный аналог PostMessage) и Synchronize(соответственно аналог SendMessage). Как пишут в ваших интернетах, они абсолютно ThreadSafe, но не знаю, настолько ли гибки, как Send/PostMessage. Мне они по некоторым причинам не понравились.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606156
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий №2Хм. Занафига? Ведь пока Send не отработает, он не вернет управление, а значит, и строка не уничтожится
не только строка, но и любой указатель, если я правильно ошибаюсь
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606214
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докя бы уж тогда лучше предпочел Queue

Судя по Synchronize ты имеешь в виду TThread.Queue

зачем создавaть сложный объект типа "анонимная функция", если передать нужно всего лишь одну строку?
лишние накладные расходы и лишняя возможность ошибиться.

нет, если мы передаём сложное и разнообразное поведение, тогда конечно

но если передать только данные надо - то и передавать надо только данные 21208990
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606234
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochзачем создавaть сложный объект типа "анонимная функция", если передать нужно всего лишь одну строку?
лишние накладные расходы и лишняя возможность ошибиться.
редко приходится передавать просто строку. Обычно 2-3 параметра. Плохо то, что Queue/Synchronize вызываются вообще без параметров, поэтому приходится городить отдельную процедуру на каждый чих. Send/PostMessage намного гибче.

Ariochно если передать только данные надо - то и передавать надо только данные 21208990
Кстати, а что ты имеешь ввиду под словом TThreadQueue.Enqueue? Мой гугл про это не знает. В сорцах fpc я этого тоже не нашел.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606238
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AriochА оно было доставлено до нужного места программы? Может окошко раньше получило WM_CLOSE и закрылось ? Или даже не окно, а весь поток повис и был отстрелен? Или ReCreateWND случился и хэндл поменялся? Или это просто было не то окно, перепутали хэндл, и оно в принципе такие мэссиджи не умеет обрабатывать ?
Основная часть этих событий - нештатные, где уже по барабану утечки памяти. Вот с закрытием да. В случае потока у меня везде стоят вычерпывалки сообщений из очереди с освобождением памяти. В случае окон вычерпывалка довольно нетривиальна.

AriochА в рамках VCL (и наверное LCL) вместo SendMessage есть TWinControl.Perform
Особо без разницы. Разве что безопаснее с точки зрения изменения хэндла, но для VCL объектов в любом случае лучше сохранять объект, а не хэндл

Докне только строка, но и любой указатель, если я правильно ошибаюсь
"любой указатель" сам не уничтожается, в отличие от managed типов
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606241
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокОбычно 2-3 параметра.

record или class

ДокКстати, а что ты имеешь ввиду под словом TThreadQueue.Enqueue? Мой гугл про это не знает.

Ну да, в отличие от TThreadList готового в Delphi нет, а потому и в FPC едва ли появится

но в общем

1) можно легко написать на базе TQueue<T> - просто все методы доступа (положить в очередь, достать из очереди, проверить есть ли что-то в очереди и т.д.) обернуть через TMonitor или TCriticalSection
Если не очень мощный поток данных - то хватит вполне. В общем ,смотришь как на основе TList<T> сделан TThreadList<T> и делаешь буквально то же с TQueue<T>

А записи разной структуры оборачиваются внутрь TValue (стандартного, либо какого-то стороннего, оптимизированного по скорости). Если вообще в одной очереди надо записи разных типов класть. Но это будет копирование данных. Лучше указатель на record передавать, либо объект (он сам себе указатель).

Кстати, кажется mORMot до появления в D2009 Advanced Record таки пользвоался старыми turboPascal-style объектами, потму что они намного быстрее создаются/убиваются, чем дельфийские классы. Как раз для передачи данных

2) в интернете полно статей на тему, недавно вышла одна, но там была очередь типа named pipes - в ней строго один писатель и строго один читатель, зато безблокировочная. Но опять же для delphi, насколько сложно ее перетащить будет в fpc/linux хз. Если можно, и читатель один (на примере другой ветки - в службе Windows 10 потоков перебирают окна и отсылают их названия в один поток, который пишет в БД), то никто не мешает для каждого потока генерящего данные завести отдельную очередь, а принимающий поток будет их по кругу осматривать.

3) кажется недавно кто-то переносил OmniThreadLibrary на FPC/Linux, но я сам не смотрел. Там очередь (iOmniBlockingColleciton) должна быть без блокировок. В принципе, если там на 90% сделано вдруг, то включиться в процесс "добить последние баги" можешь и ты.

Опять же в том же mORMot'e есть свой форк менеджера памяти SynScaleMM - там у каждого потока эксклюзивная lockless очередь блоков памяти на освобождение, куда другие потокаи скидывают "не свои" указатели из MemFree. Верятно ее можно за основу взять, если наивнйо блокировки (см. п. 1) не хватит.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606245
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокSend/PostMessage намного гибче.Ээээ?... Цельно катаная апишная будет гибче анонимной?! Может ты её готовить просто не умеешь?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606307
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий №2_Vasilisk_Главный недостаток обоих способов, что для Send тоже нужно дополнительно выделять память
Хм. Занафига? Ведь пока Send не отработает, он не вернет управление, а значит, и строка не уничтожитсяПотому, что строка уничтожится в обработчике. Для Вашего способа это означает, что для Send нужно все-таки вызвать NewStr, для моего - произвести манипуляцию с обнулением ссылки
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606317
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Потому, что строка уничтожится в обработчике. Для Вашего способа это означает, что для Send нужно все-таки вызвать NewStr, для моего - произвести манипуляцию с обнулением ссылки
Хм. Если обработчик рассчитан на Send, то ничего ему уничтожать не надо. А вот если он и на Send, и на Post - тогда да.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606327
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochможно легко написать на базе TQueue<T> - просто все методы доступа (положить в очередь, достать из очереди, проверить есть ли что-то в очереди и т.д.) обернуть через TMonitor или TCriticalSection
Не, я все-таки стараюсь придерживаться принципов бритвы Оккама. Для передачи одной строчки, числа или указателя на структуру городить целый раппер - по-моему, чересчур
white_niggerЦельно катаная апишная будет гибче анонимной?!
Я попытался в Queue публичной переменной сплэш-формы напрямую присвоить текст и получил в сеттере отлуп. Наверное не умею. Разбирательство отложил на потом
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606335
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий №2А вот если он и на Send, и на PostЯ это и имел ввиду
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606353
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокЯ попытался в Queue публичной переменной сплэш-формы напрямую присвоить текст и получил в сеттере отлуп. Наверное не умею. Разбирательство отложил на потомНе силён в лазаре. Но если сделаешь пример на делфе - могу глянуть что пошло не так.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39606402
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerНе силён в лазаре. Но если сделаешь пример на делфе - могу глянуть что пошло не так.
на D7 лазаревый код не взлетел, старшие версии лень ставить.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607557
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужики, посоветуйте еще.

Где лучше создавать/разрушать компоненты доступа (TIBDatabase, TTransactions и проч.): в конструкторе/деструкторе потока или в execute потока?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607566
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

Конечно же в Execute, ведь конструктор - это другой, "создающий" поток.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607569
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

без разницы где коннект создаётся. никогда проблем не было. лишь бы к нему во время работы не лезли из разных потоков.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607576
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonДок,

без разницы где коннект создаётся. никогда проблем не было. лишь бы к нему во время работы не лезли из разных потоков.Коннект - долгая операция. Смысл тогда делать запрос из бд в другом потоке, если коннект, который может быть даже дольше, чем выполнение запроса, будет в основном.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607577
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockmakhaonДок,

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

Расскажешь, как шарить контекст коннекта к БД FireBird между потоками?
Или ты снова как Мюллер, который помнит лишь как к нему Штирлиц за скрепками заходил?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607610
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockКоннект - долгая операция. Смысл тогда делать запрос из бд в другом потоке, если коннект, который может быть даже дольше, чем выполнение запроса, будет в основном.
Я немного о другом. Я про создание экземпляра коннекта (типа, FDataBase:= TIBDatabase.Create(Application)) и инициализацию параметров (DatabaseName,LibraryName и т.д.). Хочется "разгрузить" код в Execute.

Единственное сомнение, создание экземпляра объекта обычно заворачивается в try..finally, а тут в случае ошибки создания finally выполнится только в деструкторе потока. Потому и спросил.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607705
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДокYuRockКоннект - долгая операция. Смысл тогда делать запрос из бд в другом потоке, если коннект, который может быть даже дольше, чем выполнение запроса, будет в основном.
Я немного о другом. Я про создание экземпляра коннекта (типа, FDataBase:= TIBDatabase.Create(Application)) и инициализацию параметров (DatabaseName,LibraryName и т.д.). Хочется "разгрузить" код в Execute.

Единственное сомнение, создание экземпляра объекта обычно заворачивается в try..finally, а тут в случае ошибки создания finally выполнится только в деструкторе потока. Потому и спросил.
Без разницы, делай как удобнее. Коннект это не окно, которое автоматом "пристраивается" к создавшему его потоку.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607732
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДРасскажешь, как шарить контекст коннекта к БД FireBird между потоками?А зачем это? ТСу надо не это, ему надо изолированный в потоке коннект.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607738
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокХочется "разгрузить" код в Execute.Это делается по-другому, а не такими извращениями.
В Execute делается создание объектов (и удаление в finally, как ты хочешь), а между try и finally вызывается одна единственная функция - DoWork (или как хочешь назови этот статический метод).
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607785
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

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

авторРасскажешь, как шарить контекст коннекта к БД FireBird между потоками?

Ссылки, они же указатели, в помощь.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607789
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

а что мешает открыть коннект и не закрывать его? если он нужен постоянно. либо сделать пулл коннектов. у меня многопоточный пулл коннектов + ibquery занимает может строк 50 кода (раздаёт ibquery). правда, read only только. но мне как раз такой пулл нужен был.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607810
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

Сотни миллисекунд - все же сотни миллисекунд. Зачем основному потоку их тормозить (когда доп. поток создается для "работы с базой в доп. потоке"), остается непонятным.

И, да. В том же Firebird, если это 1-й коннект к базе (или не первый, но последний был "давно"), а база на десятки, сотни и т.д. гиг, то это будут совсем не сотни миллисекунд.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607814
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonYuRock,

а что мешает открыть коннект и не закрывать его? если он нужен постоянно. либо сделать пулл коннектов. у меня многопоточный пулл коннектов + ibquery занимает может строк 50 кода (раздаёт ibquery). правда, read only только. но мне как раз такой пулл нужен был.Все это прекрасно.
Не понятно только до сих пор, зачем для этого забирать у запускающего потока "сотни миллисекунд".

И, да, если у тебя пул - ты что, все его коннекты в конструкторе создаешь, что-ли? Сомневаюсь :)
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607815
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockЭто делается по-другому, а не такими извращениями.
В Execute делается создание объектов (и удаление в finally, как ты хочешь), а между try и finally вызывается одна единственная функция - DoWork (или как хочешь назови этот статический метод).
Чувствую, что идеологически верно именно так, но уж больно велик соблазн создавать объекты на автомате в конструкторе потока, не заботясь об их судьбе (и не создавать новые поля объекта для сохранения переданных в Create параметров). Потому и спросил, как делают ТруЪ-программисты :)

зы. ты чего такой нервный с утра?
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607829
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonа что мешает открыть коннект и не закрывать его?
В принципе, ничего. Но я хочу попробовать реализовать логику на мемори-датасетах. Дернул сервер, отфетчил записи на клиента - сиди, работай.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607836
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

создаются по мере надобности. запросили, есть свободный коннект - выделился. нет - создался. как только не нужен - 'вернулся' назад в пулл.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607878
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonYuRock,

создаются по мере надобности. запросили, есть свободный коннект - выделился. нет - создался. как только не нужен - 'вернулся' назад в пулл.
Ну вот. Не в конструкторе же.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39607889
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДокЧувствую, что идеологически верно именно так
Можно еще сделать класс TIBSingleConnectionThread, в котором будут
1. Созданы и в конструкторе сохранены "новые поля объекта для сохранения переданных в Create параметров"
2. В уже перекрытом Execute будет создаваться, стартовать и удаляться соединение в try finally, а так же после try будет вызываться абстрактный метод DoWork.
Докзы. ты чего такой нервный с утра?
Зуб заболел.
...
Рейтинг: 0 / 0
Lazarus: коннект в потоке
    #39608202
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockМожно еще сделать класс TIBSingleConnectionThread
Нафиг. Нарушается принцип бритвы Оккама :)
...
Рейтинг: 0 / 0
125 сообщений из 125, показаны все 5 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus: коннект в потоке
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]