Самый эффективный способ отправить изображения через процессы

Цель

Изображения передачи, сгенерированные одним процессом эффективно и в сверхвысокой скорости до другого процесса. Два процесса работают на той же машине и на том же рабочем столе. Операционной системой может быть WinXP, Vista и Win7.

Подробное описание

Первый процесс только для управления связью с устройством, которое производит изображения. Эти изображения составляют приблизительно 500x300 пкс в размере и могут быть обновлены до нескольких сотен раз в секунду. Для второго процесса нужны эти изображения для обработки их. Первый процесс использует третье лицо API для рисования изображений от устройства до HDC. Этот HDC должен быть обеспечен мной.

Примечание: Уже существует соединение, открытое между двумя процессами. Они связываются через неименованные каналы и разделяют взгляды файла с отображенной памятью.

Мысли

Как я достиг бы этой цели с как можно меньшей работой? И я имею в виду и работу для компьютера и меня (конечно, ;)). Я использую Delphi, поэтому возможно, существует некоторый компонент, доступный для того, чтобы сделать это? Я думаю, что мог всегда красить к HDC любого компонента изображения, сохранять содержание к потоку памяти, копировать содержание через файл с отображенной памятью, распаковывать его с другой стороны и красить его там к целевому HDC. Я также читал об интерфейсе IPicture, который может использоваться для маршалинга изображений. Мне нужен он максимально быстрый, таким образом, менее служебное лучше. Я не хочу, чтобы машина была подчеркнута только путем копирования некоторых изображений.

Каковы Ваши идеи? Я ценю каждую мысль об этом!

8
задан Bruce McGee 29 March 2010 в 12:29
поделиться

5 ответов

Хорошо, похоже, что файлы и каналы с отображением памяти - это правильный путь. Это не так уж плохо, потому что два процесса уже совместно используют MMF и два канала (для двунаправленной связи). Единственное, что оставалось решить, это как передать данные с минимальным количеством операций копирования.

Достаточно хорошо работающая схема выглядит следующим образом (последовательный поток):

Процесс 1 (требуется изображение)

  • дает сигнал процессу 2 (через канал 1) для сохранения изображения в общей памяти
  • перейти к спящий режим и ожидание ответа (блокирование чтения из канала 2)

Процесс 2 (предоставляет изображения)

  • по сигналу (через канал 1) пробуждается и сообщает аппаратному устройству рисовать в HDC 1 (это поддерживается общей памятью, см. ниже)
  • дать сигнал процессу 1 (через канал 2)
  • перейти в спящий режим и дождаться нового задания (через канал 1)

Процесс 1 (хочет изображение)

  • по сигналу (через канал 2 ) просыпаться и рисовать из общей памяти в место назначения HDC 2

Теперь для передачи изображения через общую память (моя цель состояла в том, чтобы использовать не более одной дополнительной операции копирования):

Процесс 2 создает HBITMAP через CreateDIBSection и предоставляет дескриптор отображения файла и смещение отображаемого представления. Таким образом, данные изображения хранятся в общей памяти. Это создает HBITMAP , который выбирается в HDC 1 (который также создается процессом 2) и с этого момента будет использоваться процессом 2.

Процесс 1 использует StretchDIBits с указателем на память отображенного представления (как описано здесь ).Кажется, это единственная функция для получения битов из памяти непосредственно в другой HDC (в данном случае HDC 2). Другие функции сначала скопируют их в какой-то промежуточный буфер, прежде чем вы сможете передать их оттуда в окончательный HDC.

Итак, в конце кажется, что битов, которые необходимо передать, примерно вдвое больше, чем в начале. Но я думаю, что это хорошо, если только не станет возможным совместное использование дескрипторов GDI между процессами.

Примечание: я использовал каналы вместо сигналов, потому что мне также нужно передать некоторые дополнительные данные.

1
ответ дан 5 December 2019 в 08:51
поделиться

Используйте общую память для передачи данных изображения и чего-то еще (именованные каналы, сокеты и т. Д.) Для координации передачи.

4
ответ дан 5 December 2019 в 08:51
поделиться

Как я вижу, у вас есть два варианта:

  1. Передать только дескриптор / указатель изображения другому процессу, так что оба процесса работают только с одной коллекцией изображений.
  2. Скопируйте содержимое изображения в другой процесс и с этого момента работайте над копией.

Какой подход лучше, зависит от вашего дизайна. Лучшим инструментом для обоих подходов были бы «файлы с отображением памяти» или «именованные каналы». Это самое быстрое, что вы можете получить. Файлы с отображением в память, вероятно, являются самой быстрой формой межпроцессного взаимодействия, но имеют недостаток в том, что в них нет встроенной парадигмы «клиент-сервер». Так что вам придется самостоятельно синхронизировать доступ к MMF. Именованные каналы, с другой стороны, почти так же быстры, но в них встроена парадигма клиент-сервер. Разница в скорости происходит в основном из-за этого.

Из-за общей скорости обновлений первый подход мог бы быть лучше, но тогда вам нужно следить за синхронизацией между процессами, чтобы они не читали и не записывали одно изображение одновременно. Также можно использовать какое-то кеширование или другие умные методы, так что вы сокращаете свой трафик до минимума. Столкнувшись с таким высоким уровнем коммуникации, всегда рекомендуется искать способы снижения этого уровня, если это возможно.

Для очень быстрой реализации IPC на основе именованных каналов вы можете использовать мою реализацию IPC . Он ориентирован на сообщения, поэтому вам не нужно беспокоиться о технических деталях канала. Он также использует пул потоков за кулисами и имеет незначительные дополнительные накладные расходы. Вы можете провести стресс-тестирование и убедиться в этом сами (типичное сообщение занимает 0.1 мс для полного цикла запрос-ответ клиент-сервер).

0
ответ дан 5 December 2019 в 08:51
поделиться

В некоторых случаях вы можете передавать дескрипторы HBITMAP между процессами. Я видел это раньше (да, на XP / Vista) и был удивлен, как и все остальные в команде, когда один из моих коллег показал мне.

Если память обслуживает меня правильно, я считаю, что он будет работать, если HBITMAP был выделен одной из функций GDI (CreateBitmap, CreateCompatibleBitmap, CreateDIBitmap и т. Д.). Дескрипторы HBIMAP, созданные LoadBitmap, не будут работать, поскольку это просто указатель. на внутрипроцессный ресурс.

Это, и я думаю, когда вы передаете HBITMAP другому процессу, не пытайтесь делать с ним ничего особенного, кроме обычных операций BitBlt.

По крайней мере, это то, что я помню. Нам повезло, потому что наши графические библиотеки уже были написаны для управления всеми изображениями как HBITMAP.

YMMV

3
ответ дан 5 December 2019 в 08:51
поделиться

Используйте файл отображения памяти .

Для справки по Delphi см. Файлы с отображением памяти в Delphi и Общая память в Delphi .

Для более универсального подхода вы можете использовать каналы или отправку растровых данных через TCP. Это позволит вам при необходимости более легко распределять данные изображения между узлами.

11
ответ дан 5 December 2019 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: