powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus: коннект в потоке
25 сообщений из 125, страница 4 из 5
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
25 сообщений из 125, страница 4 из 5
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus: коннект в потоке
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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