Цель
Изображения передачи, сгенерированные одним процессом эффективно и в сверхвысокой скорости до другого процесса. Два процесса работают на той же машине и на том же рабочем столе. Операционной системой может быть WinXP, Vista и Win7.
Подробное описание
Первый процесс только для управления связью с устройством, которое производит изображения. Эти изображения составляют приблизительно 500x300 пкс в размере и могут быть обновлены до нескольких сотен раз в секунду. Для второго процесса нужны эти изображения для обработки их. Первый процесс использует третье лицо API для рисования изображений от устройства до HDC. Этот HDC должен быть обеспечен мной.
Примечание: Уже существует соединение, открытое между двумя процессами. Они связываются через неименованные каналы и разделяют взгляды файла с отображенной памятью.
Мысли
Как я достиг бы этой цели с как можно меньшей работой? И я имею в виду и работу для компьютера и меня (конечно, ;)). Я использую Delphi, поэтому возможно, существует некоторый компонент, доступный для того, чтобы сделать это? Я думаю, что мог всегда красить к HDC любого компонента изображения, сохранять содержание к потоку памяти, копировать содержание через файл с отображенной памятью, распаковывать его с другой стороны и красить его там к целевому HDC. Я также читал об интерфейсе IPicture, который может использоваться для маршалинга изображений. Мне нужен он максимально быстрый, таким образом, менее служебное лучше. Я не хочу, чтобы машина была подчеркнута только путем копирования некоторых изображений.
Каковы Ваши идеи? Я ценю каждую мысль об этом!
Хорошо, похоже, что файлы и каналы с отображением памяти - это правильный путь. Это не так уж плохо, потому что два процесса уже совместно используют MMF и два канала (для двунаправленной связи). Единственное, что оставалось решить, это как передать данные с минимальным количеством операций копирования.
Достаточно хорошо работающая схема выглядит следующим образом (последовательный поток):
Процесс 1 (требуется изображение)
Процесс 2 (предоставляет изображения)
Процесс 1 (хочет изображение)
Теперь для передачи изображения через общую память (моя цель состояла в том, чтобы использовать не более одной дополнительной операции копирования):
Процесс 2 создает HBITMAP
через CreateDIBSection
и предоставляет дескриптор отображения файла и смещение отображаемого представления. Таким образом, данные изображения хранятся в общей памяти. Это создает HBITMAP
, который выбирается в HDC 1 (который также создается процессом 2) и с этого момента будет использоваться процессом 2.
Процесс 1 использует StretchDIBits
с указателем на память отображенного представления (как описано здесь ).Кажется, это единственная функция для получения битов из памяти непосредственно в другой HDC (в данном случае HDC 2). Другие функции сначала скопируют их в какой-то промежуточный буфер, прежде чем вы сможете передать их оттуда в окончательный HDC.
Итак, в конце кажется, что битов, которые необходимо передать, примерно вдвое больше, чем в начале. Но я думаю, что это хорошо, если только не станет возможным совместное использование дескрипторов GDI между процессами.
Примечание: я использовал каналы вместо сигналов, потому что мне также нужно передать некоторые дополнительные данные.
Используйте общую память для передачи данных изображения и чего-то еще (именованные каналы, сокеты и т. Д.) Для координации передачи.
Как я вижу, у вас есть два варианта:
Какой подход лучше, зависит от вашего дизайна. Лучшим инструментом для обоих подходов были бы «файлы с отображением памяти» или «именованные каналы». Это самое быстрое, что вы можете получить. Файлы с отображением в память, вероятно, являются самой быстрой формой межпроцессного взаимодействия, но имеют недостаток в том, что в них нет встроенной парадигмы «клиент-сервер». Так что вам придется самостоятельно синхронизировать доступ к MMF. Именованные каналы, с другой стороны, почти так же быстры, но в них встроена парадигма клиент-сервер. Разница в скорости происходит в основном из-за этого.
Из-за общей скорости обновлений первый подход мог бы быть лучше, но тогда вам нужно следить за синхронизацией между процессами, чтобы они не читали и не записывали одно изображение одновременно. Также можно использовать какое-то кеширование или другие умные методы, так что вы сокращаете свой трафик до минимума. Столкнувшись с таким высоким уровнем коммуникации, всегда рекомендуется искать способы снижения этого уровня, если это возможно.
Для очень быстрой реализации IPC на основе именованных каналов вы можете использовать мою реализацию IPC . Он ориентирован на сообщения, поэтому вам не нужно беспокоиться о технических деталях канала. Он также использует пул потоков за кулисами и имеет незначительные дополнительные накладные расходы. Вы можете провести стресс-тестирование и убедиться в этом сами (типичное сообщение занимает 0.1 мс для полного цикла запрос-ответ клиент-сервер).
В некоторых случаях вы можете передавать дескрипторы HBITMAP между процессами. Я видел это раньше (да, на XP / Vista) и был удивлен, как и все остальные в команде, когда один из моих коллег показал мне.
Если память обслуживает меня правильно, я считаю, что он будет работать, если HBITMAP был выделен одной из функций GDI (CreateBitmap, CreateCompatibleBitmap, CreateDIBitmap и т. Д.). Дескрипторы HBIMAP, созданные LoadBitmap, не будут работать, поскольку это просто указатель. на внутрипроцессный ресурс.
Это, и я думаю, когда вы передаете HBITMAP другому процессу, не пытайтесь делать с ним ничего особенного, кроме обычных операций BitBlt.
По крайней мере, это то, что я помню. Нам повезло, потому что наши графические библиотеки уже были написаны для управления всеми изображениями как HBITMAP.
YMMV
Используйте файл отображения памяти .
Для справки по Delphi см. Файлы с отображением памяти в Delphi и Общая память в Delphi .
Для более универсального подхода вы можете использовать каналы или отправку растровых данных через TCP. Это позволит вам при необходимости более легко распределять данные изображения между узлами.