|
|
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
пишется простенький DCOM-сервис с использованием midas'а. в нем фабрикой создаются экземпляры класса TDCOMmodule = class(TRemoteDataModule, IMyServ) при этом, у этого сервиса есть ещё и GUI-окно, оно же MainForm. мне нужно из экземпляра класса TDCOMmodule отправить сообщение этому окошку. если использовать из потока в котором живёт TDCOMmodule вызов Код: pascal 1. это будет безопасно? нет ли подводных камней? или есть что-то более правильное для передачи информации "главному потоку"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 18:24 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавныйэто будет безопасно? Это будет настолько безопасно насколько программист понимает что делает. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 18:40 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakovнеглавныйэто будет безопасно?Это будет настолько безопасно насколько программист понимает что делает.ну, я не настоящий сварщик, я только учусь. если тут есть где споткнуться, подскажите пожалуйста. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 18:49 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавный, Посмотри код wadman`a в соседней, недавно поднятой ветке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 18:55 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterПосмотри код wadman`a в соседней, недавно поднятой ветке.это там где 17 страниц ветка? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 19:37 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавный, а в качестве WParam, LParam что отправляешь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 20:00 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавный, В межпоточном обмене основных подводных камней - два: синхронизация и время валидности параметров, переданных по сслылке. PostMessage - потокобезопасен. Ты положил сообщение в очередь и пошел дальше. Если ты будешь передавать некие значения, которые влезут по размеру wParam и lParam, то это безопасно. Если же тебе надо передать что-то большее(доблы, строку, структуру, объект), то нужно озаботиться валидностью экземпляра и его потобезопасностью на момент выборки сообщений. Как - зависит от твоих хотелок и задумок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2018, 22:09 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Олег ТретьяковPostMessage - потокобезопасен. имхо, как раз PostMessage, потокоНЕбезопасен, если ты передаешь указатель, валидность которого будет потеряна к моменту, когда он будет извлечен из очереди сообщений для обработки основным потоком. А вот SendMessage, наоборот, не даст потоку продолжиться дальше (и завершиться), пока сообщение не будет обработано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 01:07 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
ДокОлег ТретьяковPostMessage - потокобезопасен. имхо, как раз PostMessage, потокоНЕбезопасен, если Это персональные тонкости мировосприятия или уже устал и не вник? Олег Третьяковто нужно озаботиться валидностью экземпляра и его потобезопасностью на момент выборки сообщений. - для способа с PostMessage Он может уже и не нужен в контексте потока - обработался, выплюнулся. Допустима и\или нужна блокировка потока-исполнителя? Ну дык и SendMessage в руки. Ты телепат? Я - нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 01:34 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
ДокОлег ТретьяковPostMessage - потокобезопасен. имхо, как раз PostMessage, потокоНЕбезопасен, если ты передаешь указатель, валидность которого будет потеряна к моменту, когда он будет извлечен из очереди сообщений для обработки основным потоком. А вот SendMessage, наоборот, не даст потоку продолжиться дальше (и завершиться), пока сообщение не будет обработано. Во-первых, никто не мешает испортить валидность после SendMessage. Дурковать так дурковать. Во-вторых - нафига такие multi-threaded приложения, если вызывающая нить будет ждать завершения задания в вызываемой. В третьих, да, случаи могут быть разными, к чему такая категоричность. В четвертых, SendMessage из другой нити не просто блокируется в ожидании ответа, а в процессе ожидания продолжает обрабатывать некоторые входящие сообщения и получить удивительное поведение в отдельных случаях. Если ты, конечно, не вызывал SendMessageTimeout с SMTO_BLOCK, о чем ты не упомянул. В пятых, PostMessage как апишная функция MS Windows- потокобезопасен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 01:47 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Спасибо всем за пояснения. Картина проясняется. Передавать планмруется небольшие структуры по ссылке. Поясните пожалуйста, почему ссылка может стать невалидной? Как этого избежать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 16:04 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавныйСпасибо всем за пояснения. Картина проясняется. Передавать планмруется небольшие структуры по ссылке. Поясните пожалуйста, почему ссылка может стать невалидной? Как этого избежать? Глупости, не обращай внимания. ... Тред-передатчик: в куче выделяет память под структуру. Копирует в выделенную память нужные данные. Передает ссылку в другую нить (например так, как ты собирался). После обработки данных, тред-приемник освобождает память, ссылку на которую ему передал передали. Возможные глюки: очередь сообщений не бесконечная, если приемник не будет успевать обработать - сообщения потеряются. Если структура крошечная, не более размера параметров сообщения - передавай данные прямо в параметрах, без ссылки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 16:17 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Спасибо. :) Структурые небольшие, но в параметры не влезут. Какой менеджер памяти нужно использовать: достаточно стандартного Дельфийского, или нужно Виндовый? Интенсивность передачи оных сообщений невелика. Переполнение очереди маловероятно. Да и ценность сообщений тоже не критична - по большей части информационная. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 16:36 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
неглавный, любой менеджер, лишь бы выделение памяти и освобождение в одном и том же делалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 16:57 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
чччД, спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2018, 17:01 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Код: pascal 1. 2. 3. 4. Тоже безопасно... Иногда не без удовольствием пользуюсь им :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.04.2018, 00:33 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
TThreadedQueue<T> ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.04.2018, 01:39 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
чччДВ пятых, PostMessage как апишная функция MS Windows- потокобезопасен. Каким макаром? чччДнеглавный, любой менеджер, лишь бы выделение памяти и освобождение в одном и том же делалось. Ерунда. Выделил в одном потоке, переслал второму, тот получил и удалил ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 11:26 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Ерунда. Выделил в одном потоке, переслал второму, тот получил и удалил В одном и том же менеджере, ваш Кэп. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 12:07 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Ерунда. Выделил в одном потоке, переслал второму, тот получил и удалилА есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 13:07 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
alekcvpВ одном и том же менеджере, ваш Кэп. Тогда да. Спасибо, Кэп! V.BorzovА есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. Не получить он может только в одном случае - если оно не отправится. А для этого достаточно вспомнить, что PostMessage это функция ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:32 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2alekcvpВ одном и том же менеджере, ваш Кэп. Тогда да. Спасибо, Кэп! V.BorzovА есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. Не получить он может только в одном случае - если оно не отправится. А для этого достаточно вспомнить, что PostMessage это функция Ты не видишь разницы между фактом получения сообщения из очереди и фактом его обработки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:45 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Не получить он может только в одном случае - если оно не отправится. Ложь и провокация. В любой момент цикл обработки очереди может завершиться по обычно непредсказуемым для вызывателя PostMessage причинам, не обработав при этом такие и все остальные другие сообщения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:47 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2, И что возвращает функция PostMessage? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:49 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.BorzovВасилий 2Ерунда. Выделил в одном потоке, переслал второму, тот получил и удалилА есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:50 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.BorzovВасилий 2, И что возвращает функция PostMessage? BOOL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 14:51 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterБолее того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. Да, но в этом случае PostMessage, скорее всего, FALSE вернет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:00 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockDarkMasterБолее того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. Да, но в этом случае PostMessage, скорее всего, FALSE вернет. Конечно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:02 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterYuRockпропущено... Да, но в этом случае PostMessage, скорее всего, FALSE вернет. Конечно. Ну вот, и значит, проверив результат PostMessage, можно будет сразу освободить выделенную память, указатель на которую передавался в параметры сообщения. А вот если она TRUE вернёт - то никакой гарантии освобождения памяти (или еще чего) нет, т.к. нет гарантии обработки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:09 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2, Насчет PostMessage: она не дожидается, когда адресат получит сообщение, поэтому очищать данные, например буфер передаваемой строки - ошибка. в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется. PostMessage либо доставит в итоге ссылку на удаленные данные, либо, если обеспечить их сохранность, понадеясь на то, что их удалит адресат, то нет гарантии, что тот их вообще получит, и данные не повиснут в памяти мертвым грузом. Поскольку PostMessage, само собой, отработает быстрее всего, не заставляя поток ждать ответа от другого потока, то у меня была идея собрать стэк данных, данные создаются там, и ссылка на них передается между потоками. Но тут выходит, что для обработки стека требуются его блокировки, опять же, и получается, что меняю шило на мыло, и я просто воспользовался sendmessage. Правда задача у меня гораздо проще: обмен данных исполняющего запрос потока с главным потоком приложения, чтобы то отрисовало статус запроса. К тому же, после того, как захотелось еще, чтобы юзер мог и остановить процесс, то выяснилось, что никуда не деться от SendMessage в принципе: и теперь я отправляю основному потоку приложения сообщение, он обрабатывает его, рисуя юзеру статус, при этом получает от юзера, возможно, нажатие кнопки "не хочу ждать, пусть всё прекратится, остановите это!!", и возвращаю результат передавшему потоку. В итоге, конечно, если основной поток зависнет, или в основном потоке запустят другой запрос, то все мои потоки встанут, конечно. И да, Synchronize ничем не хуже в этом смысле (обмена информации с основным потоком приложения), но дольше работает значительно. Однако использовать его для передачи неких финальных данных в конце отработки потока - вполне уместно, хотя OnTerminate делает то же самое, собственно, причем исполняется он в главном потоке. Прошу поправить, если я где-то в своих утверждениях ошибся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:11 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterV.Borzovпропущено... А есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. О! А вот это уже интересно! Спасибо за информацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:12 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterV.Borzovпропущено... А есть гарантия, что адресат это сообщение в результате получит, обработает и удалит то, что требуется удалить? Когда SendMessage, там понятно, а PostMessage не дожидается ответа, пуляет и уходит. Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. Удалось-ли хоть раз столкнуться с такой ситуацией? У меня в промышленных масштабах на откровенно дохлых машинах ни разу не вышло. :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:36 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.Borzovхотя OnTerminate делает то же самое, собственно, причем исполняется он в главном потоке Ну понятно :) Код: pascal 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:40 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
wadmanDarkMasterпропущено... Более того, при переполнении очереди сообщений - PostMessage() просто обламывается и ничего не шлет. Т.е. возможна ситуация, когда адресат просто ничего не получит. Удалось-ли хоть раз столкнуться с такой ситуацией? У меня в промышленных масштабах на откровенно дохлых машинах ни разу не вышло. :( Насколько знаю - на исскуственных тестах кто-то воспроизводил. Длина очереди 10000 сообщений, так что при желании можно что-то такое вытворить. А то, что у тебя не вышло - так радоваться нужно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:44 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRock... Ну понятно :) Код: pascal 1. 2. 3. 4. Ой, точно! :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:45 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
wadmanУдалось-ли хоть раз столкнуться с такой ситуацией? Такое легко получить, если: 1. обработчик любого сообщения зависнет, а PostMessage продолжают регулярно посылаться; 2. сообщения шлются чаще, чем обрабатываются (например, шлются каждую секунду, а обработка занимает 2 секунды). Особенности [ошибки] логики программы. Это от дохлости машин мало зависит. Ты не получал такого по двум причинам: 1. Таких ошибок не допускал; 2. На самом деле получал, но не замечал, и не ты, а твои клиенты ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:47 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
DarkMasterНасколько знаю - на исскуственных тестах кто-то воспроизводил. Ну вот... Так любой может. YuRock2. На самом деле получал, но не замечал, и не ты, а твои клиенты Мои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки. YuRockТакое легко получить, если: Не получалось почему-то. Но тут упорно об этом пишется теоретиками. Шах и мат. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:50 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
А я видел как в винде систему сообщений раком ставит. После чего адски тормозит ВСЕ при загрузке проца в 1%. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:56 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
wadmanНе получалось почему-то. Но тут упорно об этом пишется теоретиками. Шах и мат. Ну вот так вот Зачем-то же PostMessage() функцией сделали - значит предполагали, что возможна ситуация обломинго для нее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 15:59 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.Borzov...в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется... Мы все еще про мультитрейдинг? А какой смысл в таком мултитрейдинге, если нужно ждать результата обработки? Или у тебя принимающий диспетчер сообщений сразу же как-то передаст полученное сообщение какому-то следующему обработчику и сразу же выйдет на очередную итерацию обработки очереди? Что за чушь вообще обсуждается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:04 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
wadmanМои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки. Фигня. У меня поток работы с купюроприёмником PostMessage шлёт при принятии купюры Правда, недостач тоже не бывало пока. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:09 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
чччДV.Borzov...в SendMessage именно так и работаем: передаем в качестве параметра указатель на строку или структуру, а после выполнения функции - удаляем, если требуется... Мы все еще про мультитрейдинг? А какой смысл в таком мултитрейдинге, если нужно ждать результата обработки? Или у тебя принимающий диспетчер сообщений сразу же как-то передаст полученное сообщение какому-то следующему обработчику и сразу же выйдет на очередную итерацию обработки очереди? Что за чушь вообще обсуждается? Моя задача такая: открываем форму, нажимаем "выполнить запрос". Требуется, чтобы, во-первых, приложение не замерзло на время выполнения запроса, чтобы была возможность заниматься еще чем-то, вызвать, например, еще пару запросов в отдельных потоках, а во-вторых, чтобы юзер или самое приложение могли остановить запрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:13 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockwadmanМои клиенты это производство. Пропущенное сообщение это строчка в базе с логистикой. Нет строчки, нет отгрузки. Фигня. У меня поток работы с купюроприёмником PostMessage шлёт при принятии купюры Правда, недостач тоже не бывало пока. Купюры идут одним потоком и с определенной скоростью. Тут даже кпк справится. Но если кому мало 10 тыс, то в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows в ключике USERPostMessageLimit можно увеличить очередь. По умолчанию там эти самые 10000. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:15 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
чччДТы не видишь разницы между фактом получения сообщения из очереди и фактом его обработки. Нет, ты ошибаешься YuRockВасилий 2Не получить он может только в одном случае - если оно не отправится. Ложь и провокация. В любой момент цикл обработки очереди может завершиться по обычно непредсказуемым для вызывателя PostMessage причинам, не обработав при этом такие и все остальные другие сообщения. Пруфы или же сам лжешь. Где в цикле Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. Могут всплыть эти непредсказуемые причины? Варианты насильственного убиения потока не рассматриваются, это ситуации нештатные, и с ними в любом случае ничего не сделаешь. YuRockА вот если она TRUE вернёт - то никакой гарантии освобождения памяти (или еще чего) нет, т.к. нет гарантии обработки. В асинхронной модели нет никакой гарантии вообще всего. За гарантиями велком в синхронное ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:56 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.BorzovТребуется, чтобы, во-первых, приложение не замерзло на время выполнения запроса, чтобы была возможность заниматься еще чем-то, вызвать, например, еще пару запросов в отдельных потоках, а во-вторых, чтобы юзер или самое приложение могли остановить запрос. Ну а в нулевых, надо, чтобы СУБД поддерживал такую возможность. Таких СУБД не так много. А те, что поддерживают - поддерживают не всегда и/или с нюансами... Короче, в общем случае такую задачу не решить просто потоками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 16:59 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Где в цикле ... Могут всплыть эти непредсказуемые причины? Вот где (например): Код: pascal 1. 2. 3. 4. 5. 6. Или вот где: Код: pascal 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:05 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.BorzovНасчет PostMessage: она не дожидается, когда адресат получит сообщение, поэтому очищать данные, например буфер передаваемой строки - ошибка. Разумеется. Поэтому данные, отправляемые Post-ом, должны быть либо постоянными, либо уникальными - т.е. созданными исключительно для отправки. Второй вариант для случая, например, строк - это копия, выделенная в куче через NewStr. авторPostMessage либо доставит в итоге ссылку на удаленные данные, либо, если обеспечить их сохранность, понадеясь на то, что их удалит адресат, то нет гарантии, что тот их вообще получит, и данные не повиснут в памяти мертвым грузом. Не слушай YuRock, у него паранойя. Никуда сообщения из очереди не денутся, если они там уже есть и если грамотно написать обработку нештатных ситуаций. авторК тому же, после того, как захотелось еще, чтобы юзер мог и остановить процесс, то выяснилось, что никуда не деться от SendMessage в принципе: и теперь я отправляю основному потоку приложения сообщение, он обрабатывает его, рисуя юзеру статус, при этом получает от юзера, возможно, нажатие кнопки "не хочу ждать, пусть всё прекратится, остановите это!!", и возвращаю результат передавшему потоку. Неправильно выяснилось. Отправляй своему вторичному потоку тем же Post-ом, или взводи ему флаг по типу Terminated и всё. Конечно, в коде потока интервал между проверками флага (или длина очереди) д.б. небольшими, иначе отмена сработает с большой задержкой. Нет, вариант с SendMessage тоже сработает, и для простых случаев с двумя потоками он вполне приемлем ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:09 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Для полного удовлетворения достаточно создать простой поток - посредник между доп.потоками и основным потоком. Он выделяет память под передаваемые данные, он её освобождает по запросу или таймауту, либо допинывает при необходимости недошедшие данные до убитых, но восстановленных позднее потоков. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:17 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2и если грамотно написать обработку нештатных ситуаций Да, только очень грамотный программист обернёт на всякий случай вызов winapi-шных функций в try...except, а потом еще, после окончания цикла обработки сообщений (и фактического разрушения очереди сообщений), будет надеяться, что повторный Код: pascal 1. поможет именно "дообработать" оставшиеся сообщения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:25 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockВот где (например): Код: pascal 1. 2. 3. 4. 5. 6. Ерунда какая-то. Зачем в цикле очистки очереди досрочное прерывание? авторИли вот где: Код: pascal 1. 2. 3. 4. Здесь не исключено (если, конечно, не-gui потоку вообще возможно получение этого сообщения - но это если уже сам программер такое сделает, т.к. без явного прописывания это сообщение само собой от системы не приходит). У меня на этот случай сделано так Код: pascal 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:27 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockДа, только очень грамотный программист обернёт на всякий случай вызов winapi-шных функций в try...except, а потом еще, после окончания цикла обработки сообщений (и фактического разрушения очереди сообщений), будет надеяться, что повторный Код: pascal 1. поможет именно "дообработать" оставшиеся сообщения. Ну всё, пошла чушня. 1) При чем тут winapi-шные функции и try-except? try-except для своего кода, разумеется. 1.1) Вместо постоянной проверки winapi-шных функций на true бывает и Win32Check, к примеру 2) В какой Вселенной "окончание цикла обработки сообщений" означает "фактическое разрушение очереди сообщений"? Очередь жива, пока живет тред. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:31 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRock... Да, только очень грамотный программист обернёт на всякий случай вызов winapi-шных функций в try...except... Какого класса исключения от WinApi ожидаешь? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:32 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Ерунда какая-то. Зачем в цикле очистки очереди досрочное прерывание? Да, я тоже не понимаю, зачем, например, Борланд сделал такое в Forms.pas: Код: pascal 1. 2. 3. 4. 5. Василий 2если, конечно, не-gui потоку вообще возможно получение этого сообщения - но это если уже сам программер такое сделает Да, программист такое сделает, т.к. это единственный штатный механизм окончить цикл обработки сообщений. (Вот предыдущий пример - это не штатный, но тоже регулярно встречающийся). Василий 2У меня на этот случай сделано такТут уже без комментариев... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:38 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
чччДКакого класса исключения от WinApi ожидаешь? :)EPostMessageError вестимо :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:39 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockДа, я тоже не понимаю, зачем, например, Борланд сделал такое в Forms.pas: Код: pascal 1. 2. 3. 4. 5. Когда найдешь в этом коде очистку очереди сообщений не-gui потока от отправленных в очередь выделенных кусков памяти - тогда и будем разбираться, почему же это Борланд так сделал Тут уже без комментариев... Конечно без комментариев, раз возразить нечего. Есть и другой вариант - с while PeekMessage(PM_REMOVE), но у меня сделано через статус, уже не помню почему. С очередью виндовых сообщений есть один слабый момент - если запостить сообщение в момент после того, как отработает цикл очистки, но до убиения хэндла потока. Для избежания этого надо проверять Terminated перед PostMessage. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 17:52 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 21) При чем тут winapi-шные функции и try-except? try-except для своего кода, разумеется. Ну так и оберни в try-except свой "... process ...", зачем всю гору. Василий 22) В какой Вселенной "окончание цикла обработки сообщений" означает "фактическое разрушение очереди сообщений"? Очередь жива, пока живет тред. Это не так. Во вселенной, которая называется Винда. Все сообщения, полученные после QM_QUIT, будут потеряны навсегда вместе со всеми данными (при чем PostMessage, отсылавшая их, при этом вернет True). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:09 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Когда найдешь в этом коде очистку очереди сообщений не-gui потока от отправленных в очередь Это я тебе привел пример в ответ на вопрос Василий 2Зачем в цикле очистки очереди досрочное прерывание?При чем тут очистка не понятно. Это просто, еще раз, пример "досрочного" (не дожидаясь GetMessage=False) выхода из цикла обработки сообщений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:12 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2... Неправильно выяснилось. Отправляй своему вторичному потоку тем же Post-ом, или взводи ему флаг по типу Terminated и всё. Конечно, в коде потока интервал между проверками флага (или длина очереди) д.б. небольшими, иначе отмена сработает с большой задержкой. Нет, вариант с SendMessage тоже сработает, и для простых случаев с двумя потоками он вполне приемлем Итак, схема общения потока с основным потоком приложения (а именно этот вопрос автора топика интересовал, насколько я понял) предлагается такая: во-первых, забить на теоретические потери памяти при postmessage и слать строки, указав ссылки на них в качестве одного из параметров. Естественно, нельзя послать ссылку на переменную типа string, объявленную в функции, а это должна быть динамически созданная pchar-строка. Удаление памяти, выделенной на строку, производится адресатом. Ну, или более сложная структура, а не просто строка, понятно. О том, что этот Postmessage не дойдет до адресата, и тот не сможет выделенную дополнительную память отпустить, не беспокоимся, это паранойя. во-вторых, для обратной связи шлем postmessage потоку. Например, если хотим сказать ему, чтобы он закрылся. Если поток на тот момент уже самоудалился, то, собственно, не смертельно (так ли?), но вот по этой причине обращение к нему напрямую через terminate - нежелательно, если не хотим опять с блокировками зависнуть. Все верно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:20 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.BorzovО том, что этот Postmessage не дойдет до адресата, и тот не сможет выделенную дополнительную память отпустить, не беспокоимся, это паранойя. Да, всё верно, не беспокойся. А если там будет не строка, а объект класса, который в деструкторе какие-то блокировки снимает, что-то закрывает, или который должен что-то в файл или базу записать - тоже абсолютно ничего страшного. Снимут процесс, добавят в базу ручками... Никто даже не удивится, ведь наверняка будут знать, что программа написана на Делфи, который мертв, и потому отнесутся с пониманием. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:25 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockНу так и оберни в try-except свой "... process ...", зачем всю гору. Не придирайся, это наколеночный пример и к тому же это совсем не принципиально YuRockЭто не так. Во вселенной, которая называется Винда. Все сообщения, полученные после QM_QUIT, будут потеряны навсегда вместе со всеми данными (при чем PostMessage, отсылавшая их, при этом вернет True). Это как раз не так. То есть это "так" только в случае простейшего цикла begin while GetMessage do ... end;. Если же после цикла GetMessage выполняется цикл очистки, как я указывал, то ничего не теряется. Если хочешь, проверь сам: В execute: Код: pascal 1. 2. 3. 4. 5. Где-то вне вторичного потока Код: pascal 1. 2. YuRockЭто я тебе привел пример в ответ на вопрос Василий 2Зачем в цикле очистки очереди досрочное прерывание?При чем тут очистка не понятно. Это просто, еще раз, пример "досрочного" (не дожидаясь GetMessage=False) выхода из цикла обработки сообщений. Зачем мне синтетический пример досрочного выхода? Да и в любом случае, пусть эта проверка сделает Break. Потом она попадет на очистку и все закончится хэппи-эндом. В чем твое возражение-то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:34 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
V.Borzovво-первых, забить на теоретические потери памяти при postmessage и слать строки, указав ссылки на них в качестве одного из параметров. Естественно, нельзя послать ссылку на переменную типа string, объявленную в функции, а это должна быть динамически созданная pchar-строка. Дело вкуса, мне например больше удобен вариант NewStr(ps); ps^:=strtosend; ну и при получении - DisposeStr автор Удаление памяти, выделенной на строку, производится адресатом. И не забыть удалить, если PostThreadMessage вернул false. авторО том, что этот Postmessage не дойдет до адресата, и тот не сможет выделенную дополнительную память отпустить, не беспокоимся, это паранойя. При должном проектировании это так. По крайней мере, оппонент данного подхода до сих пор не предоставил вменяемых возражений. авторво-вторых, для обратной связи шлем postmessage потоку. Например, если хотим сказать ему, чтобы он закрылся. Если поток на тот момент уже самоудалился, то, собственно, не смертельно (так ли?) Конечно не смертельно, PostThreadMessage вернет false и по GetLastError = ERROR_INVALID_THREAD_ID можно будет понять, что он уже помер. автор, но вот по этой причине обращение к нему напрямую через terminate - нежелательно, если не хотим опять с блокировками зависнуть. Ничего страшного, если только тред не FreeOnTerminate. terminate просто ставит булевское поле terminated в true и никого не блокирует ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:41 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2 Код: pascal 1. А PostQuitMessage тебе встречать не приходилось? Ну да ладно. Василий 2Если же после цикла GetMessage выполняется цикл очистки Давай про цикл очистки не будем, просто вообще, ну не смешно. Василий 2проверь самКак раз проверил и нашел интересный нюанс. Опровергающий один (только один) из моих примеров, когда сообщения могут остаться необработанными. Оказывается (вполне вероятно, что это недавно Майкрософт запилил так - раньше я такого поведения не помню), что после PostQuitMessage в GetMessage не приходит WM_QUIT, пока очередь сообщений не станет пуста (именно пуста). А после него - в PostMessage возвращается ошибка. Т.ч. да - если GetMessage вернул 0 - да, то PostMessage больше не сработает, тут я был неправ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 18:59 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockА PostQuitMessage тебе встречать не приходилось? Ну да ладно. А покажи-ка мне, как через PostQuitMessage послать WM_QUIT другому потоку авторДавай про цикл очистки не будем, просто вообще, ну не смешно. Замять тему, когда возразить нечего? Достойный ход, да. Василий 2Опровергающий один (только один) из моих примеров, когда сообщения могут остаться необработанными. Из двух примеров один опровергся, а другой насквозь надуман :D ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 19:23 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Из двух примеров один опровергся, а другой насквозь надуман :D 1. Заметь, опровергся мной, а не тобой, который советовал и продолжает советовать какие-то бредовые "циклы очистки" для разрушенной, закрытой очереди. 2. Ты меня спросил: "зачем искусственно прерывать цикл?" Я ответил, что так может быть построена логика программы (и циклы при этом могут быть чужими, в которые не удастся наставить костылей). Привел пример. Он тебе не понравился. Если ты думаешь, что я буду шарашить тебе примеры, пока хоть один из них тебя не "устроит" - ты ошибаешься. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 19:31 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Замять тему, когда возразить нечего? Достойный ход, да.Ок, хорошо, я во всем не прав. Используй "циклы очистки" и дальше. Только другим советовать не надо нафантазированный бред. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.04.2018, 19:33 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRock1. Заметь, опровергся мной, а не тобой, который советовал и продолжает советовать какие-то бредовые "циклы очистки" для разрушенной, закрытой очереди. 1. Доказательства того, что внутри Execute очередь может разрушиться от прихода WM_QUIT, будут (для буквоедов: TerminateThread не рассматривается)? Без доказательств бред - это как раз то, что утверждаешь ты. 2. Твоё опровержение играет малую роль, даже если бы поведение функций было прежним, твой пример все равно бы не сыграл (для буквоедов: рассматриваем цикл очистки второго варианта, с GetQueueStatus). 3. Я всё ещё жду примера, как через PostQuitMessage отправить WM_QUIT другому потоку автор2. Ты меня спросил: "зачем искусственно прерывать цикл?" Я ответил, что так может быть построена логика программы (и циклы при этом могут быть чужими, в которые не удастся наставить костылей). Привел пример. Он тебе не понравился. Если ты думаешь, что я буду шарашить тебе примеры, пока хоть один из них тебя не "устроит" - ты ошибаешься. Вообще не в кассу. Я тебя спросил, где в цикле вычерпывания присланных сообщений при завершении потока может встретиться необходимость искусственного прерывания. Ты так ничего и не ответил. Только замечание с окончанием цикла GetMessage по приходу WM_QUIT было корректным, но и то в моем коде это давно предусмотрено, здесь же кусок был написан на коленке. В общем, подведу итог. Ты обвиняешь меня во лжи (что, кстати, весьма нагло - спишу на юношеский максимализм) авторЛожь и провокация. В любой момент цикл обработки очереди может завершиться по обычно непредсказуемым для вызывателя PostMessage причинам, не обработав при этом такие и все остальные другие сообщения. при этом не приведя никаких доказательств того, что грамотный код обработки закроет все возможные причины прерывания (для буквоедов: кроме нештатного вмешательства). Кроме того, кидаешь еще кучу ложных язвительных утверждений, также являющихся беспочвенными, а на предложение их обосновать скрываешься в кусты. То, что механизм очистки очереди сообщений не влезает в твой разум - это твои личные трудности, на которые мне начхать. Но не надо выдавать свою некомпетентность за признанные истины - новички могут принять за чистую монету, и дурь размножится. А ее и так хватает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2018, 11:05 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Кстати, несмотря на хамлоидность, ты натолкнул меня на соображение насчет сообщений, присланных в момент после очистки очереди и до разрушения потока. За это спасибка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2018, 11:10 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Доказательства того, что внутри Execute очередь может разрушиться от прихода WM_QUIT, будут (для буквоедов: TerminateThread не рассматривается)? Без доказательств бред - это как раз то, что утверждаешь ты.Доказательства - это код Майкрософт. В интернете его полно, ищи и разбирайся. Я же руководствуюсь документацией и поведением функций, замеченным в результате опыта использования. Да, после обработки WM_QUIT очередь закрыта для использования, и даже возобновить ее сначала не удастся. Зачем ты сюда втянул TerminateThread, для меня тайна. Василий 2Я всё ещё жду примера, как через PostQuitMessage отправить WM_QUIT другому потокуЖди. С таким же успехом можешь подождать, пока я тебе котлет нажарю. Я нигде не говорил, что такое возможно, даже думал, что такое в голову прийти может. Василий 2Я тебя спросил, где в цикле вычерпывания присланных сообщений при завершении потока может встретиться необходимость искусственного прерывания. Ты так ничего и не ответил.Очередная лож. Я тебе ответил в 1-м же ответе: там, где встретится такая необходимость с точки зрения логики работы программы - флаг какой-то взвелся - прерываем очередь и всё, до свидания. Василий 2не надо выдавать свою некомпетентность за признанные истины - новички могут принять за чистую монету, и дурь размножится. А ее и так хватает.Да, да, я уже писал, что с тобой полностью во всём согласен. Дообрабатывай очередь и дальше после ее закрытия. И не забывай, как ты грамотно советовал, проверять на not Terminated перед PostThreadMessage - это тоже наверняка сделает код более грамотным и надежным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2018, 11:48 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Ох, такое ощущение, что пытаешься религиозному фанатику времен раннего средневековья объяснить теорию эволюции... всё то же самое - полная уверенность в непогрешимости собственных доводов, отсутствие каких-либо доказательств, избирательная глухота на самые неудобные доводы оппонента и перевирание остальных. Подобная беседа совершенно бессмысленна и лишь пустая трата усилий. Тем не менее, надо признать, в процессе всё же удалось набрести на полезные соображения, хоть это и не заслуга YuRock. На всю понаписанную им чушь отвечать не буду, это как об стену горох, возьму только упорно культивируемую им концепцию "разрушения очереди сообщений". Итак: YuRockДа, после обработки WM_QUIT очередь закрыта для использования, и даже возобновить ее сначала не удастся. Вот Код: 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. Запусти и нажимай на кнопки. После того, как получишь сообщение 'Thread finished', можешь возвращаться xD. Только мышку не протри xD Наверняка последует заявление, что код написан криво, пробелы расставлены не так и использовать Функцию_X может только полный нуб, в глаза не видевший MSDN и прочая лабуда, но вдруг попадем на редкий момент просветления. Так, с шелухой разобрались, теперь к полезному - вдруг кто-то придет сюда из поиска и доберется до этого поста. Организация Execute потока, к которой я пришел, такова: Код: 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. 1. Поток можно завершить как послав сообщение (PostThreadMessage(WM_QUIT)), так и через Terminate. 2. При завершении через Terminate надо обязательно послать "сигнальное" сообщение, т.к. поток может зависнуть на GetMessage, если его очередь будет пуста 3. Нюанс: есть вероятность пропажи сообщений, если они будут отправлены в период между последним ProcessMsg и разрушением потока (ExitThread). Для избежания этого надо убедиться, что Terminated потоку не будут отправляться сообщения - к примеру, можно вообще закрыть ThreadID от доступа извне, вместо него добавив метод PostMessage, который будет проверять флаг Terminated. Разумеется, это не относится к "сигнальному" сообщению из п.2 - его слать нужно в любом случае. 4. Используемая мной ранее функция GetQueueStatus оказалась вещью в себе, вопреки описанию (весьма туманному, кстати) выдающей странные результаты. Например, она может вернуть <>0 при пустой очереди. Поэтому я заменил ее на PeekMessage, которая с такими параметрами идеальна для задачи очистки. 5. Схема Execute, разумеется не фиксирована - можно добавлять try-except в зависимости от задачи, вместо ProcessMsg можно сделать обработку в основном цикле, а чисто удаление выделить в отдельную FreeMsgData и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.04.2018, 16:52 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Запусти и нажимай на кнопки. После того, как получишь сообщение 'Thread finished', можешь возвращаться xD О, ты молодец :) Нашёл случайно еще один момент, в котором я немного ошибался: да, действительно, после обработки WM_QUIT теоретически еще можно иногда дождаться сообщений с помощью повторного цикла GetMessage. Разумеется, только в том случае, если WM_QUIT был послан только один раз. Замени вот это Василий 2 Код: pascal 1. 2. на это Код: pascal 1. 2. 3. 4. И увидишь, как неожиданно для тебя начнет работать твой пример. Василий 2 Наверняка последует заявление, что код написан криво Василий 2 Код: pascal 1. 2. Как красиво и грамотно заставлять поток работать еще неизвестное количество времени после Terminate. Для тех, кто "придет сюда из поиска и доберется до этого поста": не надо использовать эту шелуху. Ваши потоки всегда должны адекватно реагировать на команду "закрыться", а не висеть еще неизвестно сколько. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.04.2018, 18:11 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
YuRockНашёл случайно еще один момент, в котором я немного ошибался: да, действительно, после обработки WM_QUIT теоретически еще можно иногда дождаться сообщений с помощью повторного цикла GetMessage. Разумеется, только в том случае, если WM_QUIT был послан только один раз. *фейспалм* случайно, теоретически, иногда дождаться... тут программирование или гадание на кофейной гуще? Ты вообще осознал суть примера? Она в том, что ловить GetMessage-ом WM_QUIT можно сколько угодно раз, ничего с очередью от прихода этого сообщения не делается. Можешь закомментить вот эти строки Код: pascal 1. 2. 3. и пожалуйста, бесконечная отправка WM_QUIT потоку без каких-либо последствий. YuRockЗамени вот это ... И увидишь, как неожиданно для тебя начнет работать твой пример. Заменил. Всё циклится. В выхлопе данные строки: Debug Output: WM_QUIT received but we're still alive! Got messages: 10 Process Project3.exe (6112) - получили первый WM_QUIT Debug Output: Cleanup done: message count 1 Process Project3.exe (6112) - съели второй WM_QUIT Всё ожидаемо. Где удивляться? YuRockКак красиво и грамотно заставлять поток работать еще неизвестное количество времени после Terminate. Для тех, кто "придет сюда из поиска и доберется до этого поста": не надо использовать эту шелуху. Ваши потоки всегда должны адекватно реагировать на команду "закрыться", а не висеть еще неизвестно сколько. Теперь я окончательно убедился, что ты существуешь в какой-то иной реальности, где плюшевые единорожки едят радугу. Во-первых, поток по определению делает что-то продолжительное, он может висеть на ожидании любой синхронной операции либо выполнять суровые вычисления, и команда "закрыться" ему будет сугубо побоку, пока он не доделает задачу. Так что всегда надо закладываться на "неизвестное количество времени после Terminate". Во-вторых, в данном случае "неизвестное количество времени" - это максимум (T_call + T_case + T_FreeMem)*10000. Это всё занимает десятки миллисекунд. Конечно, есть системы, где и это играет роль, но в них явно не будут создавать и удалять по сотне потоков в секунду. Единственный вариант, когда завершение может затянуться - это если после Terminate потоку продолжают сыпать сообщения, причем с огромной скоростью, сравнимой с (T_call + T_case + T_FreeMem). Но это фича метода, и я указал, как такое предотвратить. В общем, довод мимо. Этак можно догнаться до того, что программа, дескать, слишком долго закрывается из-за сохранения файла конфигурации - а ну его к черту, юзер в следующий раз заново настроит, ничего с ним не сделается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 18:28 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Всё ожидаемо. Где удивляться?Там, где "Got messages:" не подряд идут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 18:57 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2Во-первых, поток по определению делает что-то продолжительное, он может висеть на ожидании любой синхронной операции либо выполнять суровые вычисления, и команда "закрыться" ему будет сугубо побоку, пока он не доделает задачу.К счастью, у меня таких потоков не бывает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 18:58 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2в данном случае "неизвестное количество времени" - это максимум (T_call + T_case + T_FreeMem)*10000. Это всё занимает десятки миллисекундОткуда ты знаешь, что будут делать и как работать потоки других людей? Ты же советуешь другим этот подход. И тут может понадобиться не только освобождение памяти, а что угодно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 19:02 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2тут программирование или гадание на кофейной гуще?Гадание всегда начинается там, где программа перестает ожидаемо (даже для пользователя) работать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 19:04 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Если хочешь надежности и предсказуемости кода лучше все делать самому. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 19:13 |
|
||
|
отправить сообщение "главному потоку" из "дочернего"
|
|||
|---|---|---|---|
|
#18+
Василий 2, Да, использование Postmessage для уведомления главного окна, когда передаваемые структуры или просто строки удаляются получателем, а осуществление обратной связи с помощью PostThreadMessage, сделало поток гораздо более самостоятельным, и там, где основной поток занимается какими-то своими делами, наш поток не висит, а продолжает работу. Отсюда и общее ускорение. Насколько я понял, если поток или объект получил сообщение, то это значит, что он получил и все предыдущие, они не ушли куда-то в никуда. А если есть опасность потери оставшихся, то этот вопрос можно решать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2018, 20:35 |
|
||
|
|

start [/forum/topic.php?all=1&fid=58&tid=2041039]: |
0ms |
get settings: |
8ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
143ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 466ms |

| 0 / 0 |
