Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Все никак не успокоюсь с "межпроцессорным взаимодействием". Использовал SendMessage (WM_COPYDATA). WndProc приложения-приемник получает сообщение сразу. Но подводный камень в том, что приложение-передатчик "висит" до тех пор, пока приложение-приемник не обработает команду и не вернет результат. При этом "обработка команды" в приемнике может занять какое-то время (ну например приемник большой файл конвертирует из одного формата в другой) и "висяк" в передатчике может оказаться критическим, что при большой нагрузке вызовет crash передатчика (ибо его оригинальный код не рассчитан на такой "висяк"). Есть обоснованное подозрение что этот метод вызывает подобные проблемы. PostMessage (WM_COPYDATA) и ему подобные использовать нельзя, т.к. он хоть и не генерирует "висяк", но при этом строка в памяти затирается до того как ее прочтут. Отсюда вывод: надо использовать другой механизм Передатчик: "послал-забыл" Приемник: "прочитал-обработал" mailslot в этом плане идеален. Даже если в message задан вопрос, на который нужен ответ, то ответ можно послать "обратным мылом", а мне в 99% применений ответ вообще не нужен. Но вопрос: как мне прочитать сообщение из mailslot сразу как оно там появилось? В примере: Reading from a Mailslot код такой: Код: plaintext 1. 2. 3. 4. 5. То бишь " сообщение прочтется не позднее чем через 3 секунды ". Категорически не устраивает. Надо сразу . Простые варианты вижу такие: В1. Вообще пытаться читать непрерывно Код: plaintext 1. 2. 3. 4. В2. Очень маленький интервал Код: plaintext 1. 2. 3. 4. 5. В3. Таймер с очень маленьким интервалом Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. По сути все три метода предполагают непрерывный и бессмысленный долбеж одного и того же кода, что мне и не нравится. Т.е. насколько вообще чреват высокочастотный долбеж таймерами, когда чего-то ждешь а оно само не стучится (как в случае с оконными сообщениями)? Вообще я смотрю в описание ф-ции GetMailslotInfo function GetMailslotInfolpReadTimeout [out, optional] The amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. This parameter is filled in when the function returns. This parameter can be NULL. Во всех примерах и то что я научился использовать, в ReadSlot() применяется конструкция: Код: plaintext 1. 2. 3. 4. 5. Т.е. ReadSlot возвращает сразу вне зависимости от наличия/отсутствия сообщений. А м.б. надо сделать так? Не? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Исходя из того что в оригинальном main() по любому используется Код: plaintext 1. 2. (чтоб приложение не "вышло") то почему бы не воткнуть туда цикл что выше вместо пустого? main()-поток меня вполне устраивает для обработки message-ей. Идея правильная? P.S. Просьба. Не советуйте мне здесь про пайпы (сыт глюко-тестами с ними по горло) или про сокеты (не хочу). Я задал конкретный вопрос про mailslot. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 19:04 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77подводный камень в том, что приложение-передатчик "висит" до тех пор, пока приложение-приемник не обработает команду и не вернет результат. Если тебе на передатчике этот результат не нужен, просто заставь приёмник быстренько скопировать данные в свой буфер и верни его сразу, ещё до того как начнёшь обработку. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 19:23 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, Mailslot (как и пайпы, и сокеты) поддерживают асинхронное чтение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 19:25 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Идея правильная? Правильная идея: выкинуть GetMailslotInfo() к ЧМ и сразу повеситься на ReadFile() пока сообщение не придёт. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 19:27 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovДмитрий77подводный камень в том, что приложение-передатчик "висит" до тех пор, пока приложение-приемник не обработает команду и не вернет результат. Если тебе на передатчике этот результат не нужен, просто заставь приёмник быстренько скопировать данные в свой буфер и верни его сразу, ещё до того как начнёшь обработку. Что касается SendMessage (WM_COPYDATA), то я так и стал делать, когда осознал проблему. Но это не решает проблемы полностью. Если приемник VB6 (где нет роскоши из многопоточности), то даже простенький результат который "сразу" может вернуться с задержкой, если приемник уже был занят на момент прихода сообщения. Если приемник C++ с отдельным потоком для возни с сообщениями, то ДА, такой способ прокатит. Но вот путать код сборной солянкой из SendMessage и MailSlot я точно не хочу. Dimitry SibiryakovПравильная идея: выкинуть GetMailslotInfo() к ЧМ и сразу повеситься на ReadFile() пока сообщение не придёт. Не думаю, что идея правильная. GetMailslotInfo как минимум возвращает lBufferSize -число байтов в сообщении, которое должен читать ReadFile. А чем плох законный параметр lpReadTimeout = INFINITE в GetMailslotInfo (ну или просто большое число по циклу)? Ну ждет себе и ждет (по документации Microsoft, без долбежа). Как будет сообщение, прочитает его и будет ждать следующего. Типа callBack, только поток висит - ну так этот поток итак ничего не делает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 20:48 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, ну сделай отдельным потоком, в этом обсуждении букв больше чем в коде ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 20:54 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Изопропил, Код наляпать несложно. Хотя менять IPC метод по всему проекту не наляпав формальной ошибки, это не 5-минутная процедура. Я вот накатал SendMessage, долго старался, а потом понял подводные камни о кот. упомянул. Но хотелось бы получить таки четкий ответ на 2 вопроса: 1.Т.е. насколько вообще чреват высокочастотный долбеж таймерами (либо цикл<+Sleep()>), когда чего-то ждешь а оно само не стучится (как в случае с оконными сообщениями)? Потому что в VB6 например (с одним потоком) таймер- это чуть не единственный способ в такой ситуации. Здесь нужен общий но аргументированный ответ. 2. GetMailslotInfo (INFINITE) -в цикле -это нормальный вариант? В отдельном main() потоке, кот. после инициализации C++ приложения все равно зациклен через Sleep()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 21:21 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, нить начисто потерял. Windows сообщения в программе обрабатываются? Дмитрий77Исходя из того что в оригинальном main() по любому используется Код: plaintext 1. 2. а кто полезную работу делает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 22:20 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Изопропила кто полезную работу делает? Если интересно, то Код: plaintext 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. Дальше цепочку раскручивать (к вопросу отношения не имеет)? Суть в том, что main() после запуска всего многопоточного хозяйства остается без работы (нулевой цикл чтоб не вышла и вся конструкция не рухнула). Посему можно думаю ожидание сообщений прям туда и пихать без самопальных CreateThread(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:24 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
ИзопропилWindows сообщения в программе обрабатываются? В настоящий момент ДА. Через при-аттаченное мной к консоли окно. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Но я хочу это окно вообще убрать и принимать Message-ы на mailslot. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:31 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, ну тогда спокойно крути в цикле ReadFile с большим таймаутом GetMailslotInfo - не нужен в данном случае, максимальный размер сообщения при создании мейлслота известен. В вот когда потребуется ожидать одно событие из нескольких -тогда другой разговор будет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:34 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Но я хочу это окно вообще убрать и принимать Message-ы на mailslot. убирай, в чём проблема( кстати, окно не обязано быть видимым) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:37 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Изопропилмаксимальный размер сообщения при создании мейлслота известен Ну, я макс. размер никогда не ограничиваю: Код: vbnet 1. Хотя там кажется есть документальное ограничение. Изопропилну тогда спокойно крути в цикле ReadFile с большим таймаутом GetMailslotInfo - не нужен в данном случае, А почему вы все так дружно против GetMailslotInfo с большим/бесконечным таймаутом? У меня ощущение что суть там одна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:45 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77А почему вы все так дружно против GetMailslotInfo потому что он просто не нужен ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:50 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77Но я хочу это окно вообще убрать и принимать Message-ы на mailslot. убирай, в чём проблема( кстати, окно не обязано быть видимым) Конечно уберу. Тем более в связи с этим окном у меня main() счас делает другой цикл: Код: plaintext 1. 2. 3. 4. 5. 6. А кто сказал, что оно видимо. Оно же у меня HWND_MESSAGE (специально для этих целей). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2014, 23:50 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
авторGetMailslotInfo с большим/бесконечным таймаутом? Похоже это не то и любая попытка задать там что-либо отличное от (LPDWORD) NULL); // no read time-out приводит к крашу. Dimitry SibiryakovПравильная идея: выкинуть GetMailslotInfo() к ЧМ и сразу повеситься на ReadFile() пока сообщение не придёт. Ты мне вот это предлагаешь? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Ну, в принципе это работает (по предварительным тестам). Но у меня вопросы: 1) Это ж отвратительный долбеж. Хуже чем таймер или Sleep(). Не? 2) Где гарантия что я не прочту 2 сообщения разом? Или что не прочту "кусок", а второй "кусок" будет прочитан в следующий раз? 3) Какой правильно брать размер buffer[]? При создании mailslot я не задаю максимальный размер: Код: plaintext 1. 2. 3. 4. По логике 65536 явный перебор конечно. Я же знаю примерную структуру своих сообщений. Но с другой стороны, сколько раз накалывался: пишешь 256, а что-нибудь куда-нибудь добавил и получаем обрубки строк. С другой стороны у меня есть NumberOfBytesRead и если оно равно запрашиваемому, то запросить след. порцию байтов как остаток строки. Но с этим возиться неохота. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 05:51 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Если приемник VB6 (где нет роскоши из многопоточности).... Напиши DLL на Си, в нее вынеси поток приема сообщений и постановку в очередь, а из VB бери из очереди и обрабатывай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 06:33 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Есть уже готовые опенсорцные DLL для обмена сообщениями. Вот пример использования. Под твою задачу подходит идеально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 06:48 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Dima T, Давай VB пока в покое оставим и SendMessage задвинем. На стороне VB я думаю удовлетворюсь таймером чтения mailslot скажем в 300мс и меня это вполне устроит. А вот на стороне C++ я хочу грамотно читать mailslot как только так сразу. Ну в принципе кажется уловил. Если написать код в виде: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. и при этом задать Код: plaintext 1. 2. 3. 4. 5. 6. то слово "timeout" будет писаться раз в 10 секунд а если Код: plaintext 1. 2. 3. 4. 5. 6. 7. то слово "timeout" вообще никогда писаться не будет Т.е. никакой "долбежки" там нет, все чудненько, с MAILSLOT_WAIT_FOREVER -идеально. Ну тогда 2 вопроса осталось: автор2) Где гарантия что я не прочту 2 сообщения разом? Или что не прочту "кусок", а второй "кусок" будет прочитан в следующий раз? 3) Какой правильно брать размер buffer[]? При создании mailslot я не задаю максимальный размер: Де-факто гарантия вроде как есть, а размер можно думаю задать побольше но не слишком, напр. char buffer[1000]; То что мусор надо ручками отсекать '\0'-символом это я уже понял после пары тестов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 07:35 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77То что мусор надо ручками отсекать '\0'-символом это я уже понял после пары тестов. Тут похоже у тебя ошибка проектирования. Подозреваю что ты вынужден насильно отсекать т.к. ты этот 0 не передаешь, отсюда проблемы с разделением сообщений. Если тебе надо передать строку "12345" то отправлять надо 6 символов, т.к. реально это массив {'1','2','3',4','5',0} Не помещает немного формат сообщения усложнить, дополнить контрольной инфой для проверки что сообщения полное. Если у тебя строки передаются, то я бы так сделал: строка из двух частей "NN\tTTTT" где NN размер, TTTT текст сообщения. Например "5\tABCDE", далее отправляешь 8 байт при получении проверяешь что последний 0 и формат соблюдается 5 == strlen("ABCDE"), если что-то не совпало - отправляешь обратно "syntax error", формат соблюден - обрабатываешь. По поводу MAILSLOT_WAIT_FOREVER - недостаток один: выйти из цикла сможешь только по команде извне. С маилслотами не работал, но думаю не помешает какой-то контроль что слот не умер, иначе зациклится постоянно выпадывая в else ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 08:07 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Dima TДмитрий77То что мусор надо ручками отсекать '\0'-символом это я уже понял после пары тестов. Тут похоже у тебя ошибка проектирования. Подозреваю что ты вынужден насильно отсекать т.к. ты этот 0 не передаешь, отсюда проблемы с разделением сообщений. Правильно подозреваешь. Я тестировал VB-шной ф-цией: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. И ф-ция эта писалась под VB->VB, а не под VB->C++ Но там другой принцип считывания (я использую GetMailslotInfo). Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. И мне там этот '\0' извини нафиг не нужен, если я его буду дописывать у меня на VB-приемнике ничего кроме лишних проблем не добавится. А в C++ у меня массив чаров, да я еще и один и тот же(с избытком длины) использую. Естественно без '\0' он мне его не обрубает. Ну, согласен, надо тогда в сторону C++ mailslot-а чуть модифицированной ф-цией посылать: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 08:54 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77А в C++ у меня массив чаров, да я еще и один и тот же(с избытком длины) использую. Естественно без '\0' он мне его не обрубает. Ну, согласен, надо тогда в сторону C++ mailslot-а чуть модифицированной ф-цией посылать ... не уверен что VB хранит последний 0, лучше так чтобы наверняка: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 09:02 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Dima Tт.к. ты этот 0 не передаешь, отсюда проблемы с разделением сообщений. Не, проблем с разделением из-за этого точно не возникает. Я вообще пока проблем с разделением не вижу. Я просто спросил: а вдруг? Dima TНе помещает немного формат сообщения усложнить, дополнить контрольной инфой для проверки что сообщения полное. Если у тебя строки передаются, то я бы так сделал: строка из двух частей "NN\tTTTT" где NN размер, TTTT текст сообщения. Например "5\tABCDE", далее отправляешь 8 байт при получении проверяешь что последний 0 и формат соблюдается 5 == strlen("ABCDE"), если что-то не совпало - отправляешь обратно "syntax error", формат соблюден - обрабатываешь.. Ну, не думаю что эти усложнения нужны Dima TПо поводу MAILSLOT_WAIT_FOREVER - недостаток один: выйти из цикла сможешь только по команде извне. Имя этой волшебной команды "taskkill.exe" -ну или API в том же духе. Dima TС маилслотами не работал, но думаю не помешает какой-то контроль что слот не умер, иначе зациклится постоянно выпадывая в else Ну, судя по опыта внедрения слот вещь неубиваемая, пока жив процесс. Проблема может возникнуть при создании слота, если уже запущен экземпляр приложения (!!! в том числе и под другим аккаунтом). Т.е. на одном компе не может быть двух слотов с одним именем. Ну, с SendMessage проблема такая же, отправитель найдет только одно окно (если их несколько) туда и будет посылать. Но, правда не совсем. Будет найдено окно под своим аккаунтом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 09:14 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Dima Tне уверен что VB хранит последний 0, лучше так чтобы наверняка: Код: plaintext 1. В данном случае это добавление бессмысленно. При конвертации vb String в C++ ноль дописывается автоматически. Просто без +1 он не пишется в сообщение. Вот за этим то я его и убил в VB->VB чтоб исключить "не уверен, лучше так чтобы наверняка". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 09:20 |
|
||
|
Как сделать так чтоб сообщения из mailslot читались "сразу как оно там появится"?
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Dima Tт.к. ты этот 0 не передаешь, отсюда проблемы с разделением сообщений. Не, проблем с разделением из-за этого точно не возникает. Я вообще пока проблем с разделением не вижу. Я просто спросил: а вдруг? Есть подозрение что доставляются сообщения по одному, т.к. это все-таки подсистема ориентированная на сообщения, а не на потоковую передачу. Поизучай MSDN, если найдешь что гарантируется доставка всегда по одному и целиком, то вообще можешь не заморачиваться с нулями, а отсекать нулем как изначально сделал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2014, 09:21 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38600364&tid=2019581]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
41ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 14ms |
| total: | 158ms |

| 0 / 0 |
