2015-12-23 1 views
0

У меня есть процесс c, которому необходимо отправить много c-структур (примерно 10 000 в секунду) в java-процесс, который должен помещать данные в соответствующий класс.Отправка структур из c в java-процесс

Размер данных, которые необходимо отправить, составит около 50-100 байт за пакет.

Задержка связана с тем, что данные должны отображаться в реальном времени, поэтому я ищу альтернативы моему текущему решению.

В настоящее время я делаю это с JNI и очередью сообщений POSIX. Есть ли лучший способ, чем использование JNI и очередей сообщений/труб? Я где-то читал, что при вызове методов JNI часто бывает много накладных расходов. Может ли это стать проблемой, когда нужно отправить много данных?

Другим решением, которое я имел в виду, было просто написать данные в UNIX Socket и проанализировать его в java.

+0

Нужно ли использовать код в Java и один в C для запуска в двух отдельных процессах? –

+0

@SamuelAudet Да, данные поступают из плагина для IDS, который должен как можно быстрее обрабатывать сетевые пакеты. После обработки пакета мы отправляем декодированные данные в другой процесс, который обрабатывает граф. Кроме того, c-процесс запускается как служба, в то время как Java-программа должна быть независимо запущена или остановлена, когда захочет, не влияя на запущенную программу c. –

+0

Итак, я предполагаю, что файл с отображением памяти будет самым эффективным способом сделать это, и это выглядит так: http://stackoverflow.com/a/6412333/523744 –

ответ

1

Если вы должны обрабатывать данные в конечном итоге с использованием Java, а затем удалить как можно больше промежуточных шагов.

Если вы можете прочитать данные непосредственно в Java (обходя JNI и код C), тогда сделайте это. Избегайте JNI, очередь сообщений и (предположительно) этап, на котором C принимает данные. Очередь также не может помочь в задержке.

Если данные начинаются с C-дружественной формы, недружественной к Java, тогда я рассматриваю возможность полностью переключиться на C или C++, а не на обработку в Java вообще.

+0

Проблема в том, что приложение где информация поступает, находится в c и i (моя команда), просто расширяя ее. Мы должны использовать java, потому что за исключением двух человек, никто не знает, как программировать в c/C++, поэтому мы выбрали java (команда из 6 человек). Часть c отвечает за декодирование сетевых пакетов для системы обнаружения вторжений. Это должно быть как можно быстрее и сделано в c. Затем мы отделили некоторые данные к программе java, которая строит график из данных для визуализации сети. –

+0

Если ваша цель заключается в построении графика для визуализации результатов, то скорость, даже в реальном времени, вряд ли станет серьезной проблемой. Вы действительно столкнулись с какой-либо реальной проблемой производительности? Также вероятно, что вы можете построить граф на C и передать минимум данных на Java (структура графика, в отличие от отдельных элементов данных). – StephenG

+1

@MarkG * Мы должны использовать java, потому что за исключением двух человек, никто не знает, как программировать в c/C++, поэтому мы выбрали java (команда из 6 человек). * Если вы не знаете, как программировать на C/C++, вы у вас будет очень сложная кодировка времени JNI, где вам не только нужно знать, как закодировать на Java ** и ** C, но и вы должны понимать, как работают оба языка. Если вы уже кодируете JNI, вы знаете, как кодировать C как минимум. –

0

Вы можете достичь высокой пропускной способности, избегая ненужного копирования памяти. Передавайте данные между C и Java через direct byte buffers. Со стороны Java вы можете читать данные в буферах байтов и копировать значения в поля объекта. Для двух процессов, разговаривающих друг с другом, вы можете использовать файл с отображением памяти для этого (для этого вы использовали бы MappedByteBuffer).

Для чего-то более простого, но с немного более накладными расходами, вы можете просто использовать stdin/stdout каждого процесса для связи и отправки данных таким образом. Или, как вы сказали, сокет - это еще один вариант.

С 10 000 структур по 100 байт каждый будет обрабатывать 1 МБ/секунду. На самом деле это не должно быть проблемой для современного оборудования (для одного из моих проектов мне удалось легко преодолеть 1 ГБ/секунду между прямыми буферами и объектами Java с примитивными + массивами, но все это было в одном процессе между JNI и Java).

Сначала вы можете использовать более простой подход (stdin/stdout), и сначала убедитесь, что это достаточно быстро, прежде чем копаться в использовании файлов с отображением памяти.

+0

Спасибо за ввод. Я попробую замять тестовый сценарий и посмотреть, работает ли это лучше. –

0

Это, я думаю, может быть решена с использованием типичных методов IPC. Я бы использовал каналы в очереди сообщений и сокетах. Накладные расходы на очередь сообщений замедляют обработку. И трубы быстрее, чем сокеты, но не сильно.

Для вашей проблемы 10 000 структур со 100 байт на пакет достигают 1 МБ/с. Современный многоядерный процессор справится с этим без проблем.