|
|
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Коннекта и одного хватит для фоновых задач. У тебя алгоритм сейчас какой? Я-бы фоном фетчил по 200 записей и возвращал их основному потоку, а в нем-бы заливал в мемори датасет. Переброска в памяти дело шустрое, едва заметное. А при пустом результате просто выставлял-бы флаг, что данных больше нет. Хотя... Если база многопользовательская, то данные могут и появиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 08:56 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
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. Потому и вопрошал, кто где и как делает. зы. Кстати, тут интересная дискуссия развернулась по отрисовке LCL-элементов во время работы потоков. Также кем-то была высказана мысль, что для передачи строк в основной поток недопустимо использовать PostMessage, т.к. указатели на них могут "уже потеряться", пока до них доберется основной поток. Принципиальных возражений вроде нет, но ... я заметил, что Линукс элементарно "висит" пока не заменишь SendMessage на PostMessage ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 09:41 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокВернее, где проводить эту проверку. Чем AfterScroll не подошёл? Я вообще-бы не делал серфинг вперед-назад, а сделал-бы просто подгрузку в одном направлении -> вперед. Докзы. Кстати, тут интересная дискуссия развернулась по отрисовке LCL-элементов во время работы потоков. Также кем-то была высказана мысль, что для передачи строк в основной поток недопустимо использовать PostMessage, т.к. указатели на них могут "уже потеряться", пока до них доберется основной поток. Принципиальных возражений вроде нет, но ... я заметил, что Линукс элементарно "висит" пока не заменишь SendMessage на PostMessage Я давно прошел эти этапы. :) Все через сообщения (в т.ч. и строки через выделенную память) и никаких проблем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 10:10 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
wadmanЯ вообще-бы не делал серфинг вперед-назад, а сделал-бы просто подгрузку в одном направлении -> вперед. хм, а это мне в голову как-то сразу не пришло :) А датасет в памяти сможет 400К записей и больше удержать? wadmanВсе через сообщения (в т.ч. и строки через выделенную память) и никаких проблем. вот в этом-то вся и беда, надо выделять/освобождать память для передаваемых объектов - геморройно :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 11:42 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокА датасет в памяти сможет 400К записей и больше удержать? Сначала спроси у человека, сможет ли он хотя-бы тысячу записей удержать в голове. Не сталкивался с такими потребностями... Тут только тестировать, размер строки бывает разным. Докнадо выделять/освобождать память для передаваемых объектов - геморройно :) Ты же это не сам будешь делать, а напишешь для этого код, который работает за тебя. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 11:49 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Докдля передачи строк в основной поток недопустимо использовать PostMessage,Допустимо, но с умом Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 11:51 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокА датасет в памяти сможет 400К записей и больше удержать?Однонаправленный сможет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 11:52 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Докдля передачи строк в основной поток недопустимо использовать PostMessage,Допустимо, но с умом Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Классный вариант! Правда, хак. Я у себя делал через NewStr/DisposeStr. Кстати, надо еще помнить, что PostMessage может вернуть False и не отправить сообщение. То бишь в данном варианте Код: pascal 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 14:28 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Василий №2Правда, хак.Не хак. Просто понимание работы счетчика ссылок Василий №2Я у себя делал через NewStr/DisposeStr.Это лучше. Василий №2PostMessage может вернуть False и не отправить сообщение.Хорошее уточнение Главный недостаток обоих способов, что для Send тоже нужно дополнительно выделять память ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 14:44 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Это лучше. обязательным копированием содержимого строки? лучше просто очередь завести и в нее сбрасывать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 15:11 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Ariochобязательным копированием содержимого строки?Читабельнее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 15:41 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, TThreadQueue.Enqueue еще читабельнее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 17:20 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Василий №2Кстати, надо еще помнить, что PostMessage может вернуть False и не отправить сообщение. То бишь в данном варианте Код: pascal 1. 2. Пофиг. Я PostMessage использую только в некритичных случаях (в гуи инфу отослать для отображения) и то, только под линукс (он, собака, просто перестает рисовать окна, если завалить его потоком SendMessage). Для остальных случаях - только SendMessage ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 20:06 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокПофиг. Я PostMessage использую только в некритичных случаяхНе пофиг. Будет утечка памяти если не проверить результат и тупо обнулить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 20:34 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, ок, возьму на заметку. Спасибо за пояснения ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2018, 22:33 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Не хак. Просто понимание работы счетчика ссылок Не... таки хак. Ибо вмешательство во внутренний механизм. _Vasilisk_Главный недостаток обоих способов, что для Send тоже нужно дополнительно выделять память Хм. Занафига? Ведь пока Send не отработает, он не вернет управление, а значит, и строка не уничтожится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 10:18 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Не пофиг. Будет утечка памяти если не проверить результат и тупо обнулить Это ее не устранит. Хотя вероятность понизит. Но устранит только гарантия "сообщение получено, за освобождение памяти теперь отвечает другой блок программы" А "если проверить результат" - то ты просто передал какое-то сообщение Windows, не свеой программЕ, а операционке. А оно было доставлено до нужного места программы? Может окошко раньше получило WM_CLOSE и закрылось ? Или даже не окно, а весь поток повис и был отстрелен? Или ReCreateWND случился и хэндл поменялся? Или это просто было не то окно, перепутали хэндл, и оно в принципе такие мэссиджи не умеет обрабатывать ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 14:07 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокДля остальных случаях - только SendMessage Если всё это в рамках одной программы - то SendMessage хорош только для однородности с PostMessage, чтобы одно в другое превращать заменой 4-х символов. А в рамках VCL (и наверное LCL) вместo SendMessage есть TWinControl.Perform ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 14:09 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Arioch, я бы уж тогда лучше предпочел Queue(безопасный аналог PostMessage) и Synchronize(соответственно аналог SendMessage). Как пишут в ваших интернетах, они абсолютно ThreadSafe, но не знаю, настолько ли гибки, как Send/PostMessage. Мне они по некоторым причинам не понравились. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 14:29 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Василий №2Хм. Занафига? Ведь пока Send не отработает, он не вернет управление, а значит, и строка не уничтожится не только строка, но и любой указатель, если я правильно ошибаюсь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 14:30 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Докя бы уж тогда лучше предпочел Queue Судя по Synchronize ты имеешь в виду TThread.Queue зачем создавaть сложный объект типа "анонимная функция", если передать нужно всего лишь одну строку? лишние накладные расходы и лишняя возможность ошибиться. нет, если мы передаём сложное и разнообразное поведение, тогда конечно но если передать только данные надо - то и передавать надо только данные 21208990 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 15:35 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
Ariochзачем создавaть сложный объект типа "анонимная функция", если передать нужно всего лишь одну строку? лишние накладные расходы и лишняя возможность ошибиться. редко приходится передавать просто строку. Обычно 2-3 параметра. Плохо то, что Queue/Synchronize вызываются вообще без параметров, поэтому приходится городить отдельную процедуру на каждый чих. Send/PostMessage намного гибче. Ariochно если передать только данные надо - то и передавать надо только данные 21208990 Кстати, а что ты имеешь ввиду под словом TThreadQueue.Enqueue? Мой гугл про это не знает. В сорцах fpc я этого тоже не нашел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 16:02 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
AriochА оно было доставлено до нужного места программы? Может окошко раньше получило WM_CLOSE и закрылось ? Или даже не окно, а весь поток повис и был отстрелен? Или ReCreateWND случился и хэндл поменялся? Или это просто было не то окно, перепутали хэндл, и оно в принципе такие мэссиджи не умеет обрабатывать ? Основная часть этих событий - нештатные, где уже по барабану утечки памяти. Вот с закрытием да. В случае потока у меня везде стоят вычерпывалки сообщений из очереди с освобождением памяти. В случае окон вычерпывалка довольно нетривиальна. AriochА в рамках VCL (и наверное LCL) вместo SendMessage есть TWinControl.Perform Особо без разницы. Разве что безопаснее с точки зрения изменения хэндла, но для VCL объектов в любом случае лучше сохранять объект, а не хэндл Докне только строка, но и любой указатель, если я правильно ошибаюсь "любой указатель" сам не уничтожается, в отличие от managed типов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 16:07 |
|
||
|
Lazarus: коннект в потоке
|
|||
|---|---|---|---|
|
#18+
ДокОбычно 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) не хватит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2018, 16:20 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39606153&tid=2041189]: |
0ms |
get settings: |
8ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
170ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
| others: | 270ms |
| total: | 527ms |

| 0 / 0 |
