Так что я относительно новичок в IPC, и у меня есть программа на c, которая собирает данные, и программа на python, которая анализирует данные. Я хочу иметь возможность:

  1. Вызов программы на python как подпроцесс моей основной программы c
  2. Передайте структуру c, содержащую данные для обработки, процессу python
  3. Вернуть значение int из процесса python обратно в программу c

Я кратко рассмотрел Pipes и FIFO, но пока не могу найти какую-либо информацию для решения этой проблемы, поскольку, насколько я понимаю, функция fork (), например, просто дублирует вызывающий процесс, поэтому не то, что я хочу, поскольку я пытаюсь вызвать другой процесс.

4
PaddyOsmond 16 Дек 2015 в 18:08

3 ответа

Лучший ответ

О fork() и необходимости выполнения другого процесса. Это правда, что fork() создает копию текущего процесса. Но обычно это связано с exec() ( одна из различных форм), чтобы получить копию процесса для выполнения другой программы.

Что касается IPC , у вас есть несколько вариантов. Кто-то упомянул очередь - но что-то вроде ZeroMQ - это перебор. Вы можете сделать IPC с одним из нескольких механизмов.

  1. Каналы (именованные каналы или анонимные)
  2. Доменные сокеты Unix
  3. TCP или UDP через API сокетов
  4. Общая память
  5. Очереди сообщений

pipe подход самый простой. Обратите внимание, что когда вы передаете данные назад и вперед между программой на C и Python, вам нужно беспокоиться о синтаксисе передачи данных. Если вы решите использовать структуры C (которые могут быть непереносимыми), вам нужно будет распаковать данные на стороне Python. В противном случае вы можете использовать некоторый текстовый формат - комбинацию sprintf / sscanf или JSON и т. Д.

4
user3666197 16 Дек 2015 в 16:29

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

  • Ваш работник Python прослушивает новую информацию для обработки в очереди A;
  • Ваша программа на C вводит данные в очередь A;
  • Ваш работник Python обрабатывает данные и помещает результат в очередь B;
  • Ваша C-программа прослушивает новые элементы в очереди B;

Это может варьироваться, но концепция проста.

Они просты в реализации и имеют множество библиотек и инструментов, которые помогут вам в этой задаче. ZeroMQ наверняка подойдет для вас. Работает с C и Python.

0
0xd 16 Дек 2015 в 15:25

Я предлагаю рассмотреть приложение и структурировать проблемы, с которыми вы сталкиваетесь.

Многопоточность

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

Общение

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

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

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

Синхронизация против Async

Синхронный означает, что для каждого сообщения есть ответ, который должен содержаться во временном конверте конечного (обычно как можно меньшего) размера. Это для того, чтобы избежать задержки. Этот шаблон лучше всего использовать, когда вам нужно точно контролировать происходящее или вам нужно ответить на вопрос своевременно. Фактически, именно так http работает для загрузки веб-страниц: всякий раз, когда вы загружаете веб-сайт, вы хотите видеть его содержимое прямо сейчас. Этот шаблон называется REQ uest / REP ly

Асинхронный часто используется в случае интенсивной обработки: производитель данных (например, интерфейс базы данных или датчик) отправляет большую часть данных в рабочий поток, не ожидая ответа. Затем рабочий поток начинает выполнять свою работу с данными и по завершении отправляет результаты приемнику данных / пользователю. Этот шаблон называется PUB lish / SUB писец.

Есть много других, но они формируют основы общения.

Маршаллинг

Другая проблема, с которой вы сталкиваетесь, заключается в том, как структурировать передачу данных, сортировку. Как получить значение и содержание ваших данных из одного контекста в совершенно другой. Например, из вашей части C в вашу часть Python. Поддержание сериализации библиотек утомительно и опасно, не говоря уже о склонности к проблемам обратной совместимости.

Реализация

Когда вы приходите к реализации, вам обычно нужен самый чистый и мощный код. Две вещи явно противоречат друг другу. Поэтому я обычно иду искать библиотеку, которая может делать именно то, что мне нужно. В этом случае советую попробовать ZeroMQ: он тонкий, гибкий, низкоуровневый. Это даст вам мощную среду для взаимодействия потоков, процессов и даже машин. ZeroMQ предоставляет ссылку, но вам все еще нужен протокол для запуска по этой ссылке. Чтобы избежать невероятных головных болей и упростить свою работу в отношении проблемы с маршалингом, я предлагаю вам изучить доступные библиотеки маршалинга, которые облегчают эту задачу. Cap'n proto, Flatbuffers, Буферы протокола (Google, не может опубликовать более 2 ссылок) Они позволяют легко определять ваши данные на промежуточном языке и анализировать их на любом другом языке без необходимости писать все классы самостоятельно.

Что касается трубок и общей памяти, то мое скромное мнение таково: забудьте, что они существуют.

2
Claudio 17 Дек 2015 в 10:21