powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / отправить сообщение "главному потоку" из "дочернего"
25 сообщений из 77, страница 2 из 4
отправить сообщение "главному потоку" из "дочернего"
    #39624894
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.BorzovВасилий 2,
И что возвращает функция PostMessage?

BOOL
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624911
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterБолее того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит.
Да, но в этом случае PostMessage, скорее всего, FALSE вернет.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624912
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockDarkMasterБолее того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит.
Да, но в этом случае PostMessage, скорее всего, FALSE вернет.

Конечно.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624922
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterYuRockпропущено...

Да, но в этом случае PostMessage, скорее всего, FALSE вернет.

Конечно.
Ну вот, и значит, проверив результат PostMessage, можно будет сразу освободить выделенную память, указатель на которую передавался в параметры сообщения.
А вот если она TRUE вернёт - то никакой гарантии освобождения памяти (или еще чего) нет, т.к. нет гарантии обработки.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624927
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2,

Насчет PostMessage: она не дожидается, когда адресат получит сообщение, поэтому очищать данные, например буфер передаваемой строки - ошибка. в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется. PostMessage либо доставит в итоге ссылку на удаленные данные, либо, если обеспечить их сохранность, понадеясь на то, что их удалит адресат, то нет гарантии, что тот их вообще получит, и данные не повиснут в памяти мертвым грузом. Поскольку PostMessage, само собой, отработает быстрее всего, не заставляя поток ждать ответа от другого потока, то у меня была идея собрать стэк данных, данные создаются там, и ссылка на них передается между потоками. Но тут выходит, что для обработки стека требуются его блокировки, опять же, и получается, что меняю шило на мыло, и я просто
воспользовался sendmessage. Правда задача у меня гораздо проще: обмен данных исполняющего запрос потока с главным потоком приложения, чтобы то отрисовало статус запроса. К тому же, после того, как захотелось еще, чтобы юзер мог и остановить процесс, то выяснилось, что никуда не деться от SendMessage в принципе: и теперь я отправляю основному потоку приложения сообщение, он обрабатывает его, рисуя юзеру статус, при этом получает от юзера, возможно, нажатие кнопки "не хочу ждать, пусть всё прекратится, остановите это!!", и возвращаю результат передавшему потоку. В итоге, конечно, если основной поток зависнет, или в основном потоке запустят другой запрос, то все мои потоки встанут, конечно.

И да, Synchronize ничем не хуже в этом смысле (обмена информации с основным потоком приложения), но дольше работает значительно. Однако использовать его для передачи неких финальных данных в конце отработки потока - вполне уместно, хотя OnTerminate делает то же самое, собственно, причем исполняется он в главном потоке.

Прошу поправить, если я где-то в своих утверждениях ошибся.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624932
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterV.Borzovпропущено...
А есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит.

Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит.
О! А вот это уже интересно! Спасибо за информацию.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624968
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterV.Borzovпропущено...
А есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит.

Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит.
Удалось-ли хоть раз столкнуться с такой ситуацией?
У меня в промышленных масштабах на откровенно дохлых машинах ни разу не вышло. :(
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624974
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzovхотя OnTerminate делает то же самое, собственно, причем исполняется он в главном потоке
Ну понятно :)
Код: pascal
1.
2.
3.
4.
procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624977
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanDarkMasterпропущено...


Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит.
Удалось-ли хоть раз столкнуться с такой ситуацией?
У меня в промышленных масштабах на откровенно дохлых машинах ни разу не вышло. :(

Насколько знаю - на исскуственных тестах кто-то воспроизводил. Длина очереди 10000 сообщений, так что при желании можно что-то такое вытворить. А то, что у тебя не вышло - так радоваться нужно
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624978
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock...
Ну понятно :)
Код: pascal
1.
2.
3.
4.
procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;


Ой, точно! :)
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624983
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanУдалось-ли хоть раз столкнуться с такой ситуацией?
Такое легко получить, если:
1. обработчик любого сообщения зависнет, а PostMessage продолжают регулярно посылаться;
2. сообщения шлются чаще, чем обрабатываются (например, шлются каждую секунду, а обработка занимает 2 секунды).

Особенности [ошибки] логики программы. Это от дохлости машин мало зависит.

Ты не получал такого по двум причинам:
1. Таких ошибок не допускал;
2. На самом деле получал, но не замечал, и не ты, а твои клиенты
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624987
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterНасколько знаю - на исскуственных тестах кто-то воспроизводил.
Ну вот... Так любой может.
YuRock2. На самом деле получал, но не замечал, и не ты, а твои клиенты
Мои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки.
YuRockТакое легко получить, если:
Не получалось почему-то. Но тут упорно об этом пишется теоретиками. Шах и мат.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39624994
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я видел как в винде систему сообщений раком ставит.

После чего адски тормозит ВСЕ при загрузке проца в 1%.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625001
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanНе получалось почему-то. Но тут упорно об этом пишется теоретиками. Шах и мат.

Ну вот так вот Зачем-то же PostMessage() функцией сделали - значит предполагали, что возможна ситуация обломинго для нее.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625011
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzov...в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется...

Мы все еще про мультитрейдинг?
А какой смысл в таком мултитрейдинге, если нужно ждать результата обработки? Или у тебя принимающий диспетчер сообщений сразу же как-то передаст полученное сообщение какому-то следующему обработчику и сразу же выйдет на очередную итерацию обработки очереди? Что за чушь вообще обсуждается?
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625023
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanМои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки.
Фигня. У меня поток работы с купюроприёмником PostMessage шлёт при принятии купюры
Правда, недостач тоже не бывало пока.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625024
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДV.Borzov...в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется...

Мы все еще про мультитрейдинг?
А какой смысл в таком мултитрейдинге, если нужно ждать результата обработки? Или у тебя принимающий диспетчер сообщений сразу же как-то передаст полученное сообщение какому-то следующему обработчику и сразу же выйдет на очередную итерацию обработки очереди? Что за чушь вообще обсуждается?
Моя задача такая: открываем форму, нажимаем "выполнить запрос". Требуется, чтобы, во-первых, приложение не замерзло на время выполнения запроса, чтобы была возможность заниматься еще чем-то, вызвать, например, еще пару запросов в отдельных потоках, а во-вторых, чтобы юзер или самое приложение могли остановить запрос.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625028
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockwadmanМои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки.
Фигня. У меня поток работы с купюроприёмником PostMessage шлёт при принятии купюры
Правда, недостач тоже не бывало пока.
Купюры идут одним потоком и с определенной скоростью. Тут даже кпк справится.

Но если кому мало 10 тыс, то в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows в ключике USERPostMessageLimit можно увеличить очередь. По умолчанию там эти самые 10000.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625080
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДТы не видишь разницы между фактом получения сообщения из очереди и фактом его обработки.
Нет, ты ошибаешься
YuRockВасилий 2Не получить он может только в одном случае - если оно не отправится.
Ложь и провокация. В любой момент цикл обработки очереди может завершиться по обычно непредсказуемым для вызывателя PostMessage причинам, не обработав при этом такие и все остальные другие сообщения.
Пруфы или же сам лжешь.
Где в цикле
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
try
  while not Terminated do
    GetMessage
    ...process...
except
  ...
end;
while GetMessage do
  ... just free memory ...


Могут всплыть эти непредсказуемые причины?
Варианты насильственного убиения потока не рассматриваются, это ситуации нештатные, и с ними в любом случае ничего не сделаешь.
YuRockА вот если она TRUE вернёт - то никакой гарантии освобождения памяти (или еще чего) нет, т.к. нет гарантии обработки.
В асинхронной модели нет никакой гарантии вообще всего. За гарантиями велком в синхронное
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625083
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.BorzovТребуется, чтобы, во-первых, приложение не замерзло на время выполнения запроса, чтобы была возможность заниматься еще чем-то, вызвать, например, еще пару запросов в отдельных потоках, а во-вторых, чтобы юзер или самое приложение могли остановить запрос.
Ну а в нулевых, надо, чтобы СУБД поддерживал такую возможность. Таких СУБД не так много. А те, что поддерживают - поддерживают не всегда и/или с нюансами...

Короче, в общем случае такую задачу не решить просто потоками.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625093
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2Где в цикле ... Могут всплыть эти непредсказуемые причины?
Вот где (например):
Код: pascal
1.
2.
3.
4.
5.
6.
while GetMessage do begin
  ... just free memory ...

  if ПораЗакончитьЭтотЦиклПотомуЧтоЯТакХочу = True then
    Break;
end;



Или вот где:
Код: pascal
1.
2.
3.
4.
while GetMessage do begin
  ... just free memory ...
end;
// А вот тут мы уже вне цикла, т.к. пришел WM_QUIT, хотя после этого WM_QUIT была еще гора необработанных сообщений
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625098
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.BorzovНасчет PostMessage: она не дожидается, когда адресат получит сообщение, поэтому очищать данные, например буфер передаваемой строки - ошибка.
Разумеется. Поэтому данные, отправляемые Post-ом, должны быть либо постоянными, либо уникальными - т.е. созданными исключительно для отправки. Второй вариант для случая, например, строк - это копия, выделенная в куче через NewStr.

авторPostMessage либо доставит в итоге ссылку на удаленные данные, либо, если обеспечить их сохранность, понадеясь на то, что их удалит адресат, то нет гарантии, что тот их вообще получит, и данные не повиснут в памяти мертвым грузом.
Не слушай YuRock, у него паранойя. Никуда сообщения из очереди не денутся, если они там уже есть и если грамотно написать обработку нештатных ситуаций.

авторК тому же, после того, как захотелось еще, чтобы юзер мог и остановить процесс, то выяснилось, что никуда не деться от SendMessage в принципе: и теперь я отправляю основному потоку приложения сообщение, он обрабатывает его, рисуя юзеру статус, при этом получает от юзера, возможно, нажатие кнопки "не хочу ждать, пусть всё прекратится, остановите это!!", и возвращаю результат передавшему потоку.
Неправильно выяснилось. Отправляй своему вторичному потоку тем же Post-ом, или взводи ему флаг по типу Terminated и всё. Конечно, в коде потока интервал между проверками флага (или длина очереди) д.б. небольшими, иначе отмена сработает с большой задержкой. Нет, вариант с SendMessage тоже сработает, и для простых случаев с двумя потоками он вполне приемлем
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625101
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для полного удовлетворения достаточно создать простой поток - посредник между доп.потоками и основным потоком.
Он выделяет память под передаваемые данные, он её освобождает по запросу или таймауту, либо допинывает при необходимости недошедшие данные до убитых, но восстановленных позднее потоков.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625107
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2и если грамотно написать обработку нештатных ситуаций
Да, только очень грамотный программист обернёт на всякий случай вызов winapi-шных функций в try...except, а потом еще, после окончания цикла обработки сообщений (и фактического разрушения очереди сообщений), будет надеяться, что повторный
Код: pascal
1.
while GetMessage do

поможет именно "дообработать" оставшиеся сообщения.
...
Рейтинг: 0 / 0
отправить сообщение "главному потоку" из "дочернего"
    #39625108
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockВот где (например):
Код: pascal
1.
2.
3.
4.
5.
6.
while GetMessage do begin
  ... just free memory ...

  if ПораЗакончитьЭтотЦиклПотомуЧтоЯТакХочу = True then
    Break;
end;



Ерунда какая-то. Зачем в цикле очистки очереди досрочное прерывание?
авторИли вот где:
Код: pascal
1.
2.
3.
4.
while GetMessage do begin
  ... just free memory ...
end;
// А вот тут мы уже вне цикла, т.к. пришел WM_QUIT, хотя после этого WM_QUIT была еще гора необработанных сообщений


Здесь не исключено (если, конечно, не-gui потоку вообще возможно получение этого сообщения - но это если уже сам программер такое сделает, т.к. без явного прописывания это сообщение само собой от системы не приходит).
У меня на этот случай сделано так
Код: pascal
1.
2.
3.
4.
5.
6.
    // вычерпываем все сообщения из очереди и удаляем все выделенные куски
    while GetQueueStatus(QS_ALLEVENTS) <> 0 do
    begin
      GetMessage(MsgRec, 0, 0, 0);
      ProcessMsg(MsgRec, True);
    end;
...
Рейтинг: 0 / 0
25 сообщений из 77, страница 2 из 4
Форумы / Delphi [игнор отключен] [закрыт для гостей] / отправить сообщение "главному потоку" из "дочернего"
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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