Запуск программ из C ++, обмен информацией с каналами, а затем совместная память - PullRequest
3 голосов
/ 07 февраля 2011

В настоящее время я занимаюсь разработкой модульной структуры, использующей разделяемую память на C & C ++. Цель состоит в том, чтобы иметь независимые программы на C и C ++, общаться друг с другом через общую память.

например. одна программа отвечает за считывание GPS, а другая - за обработку данных от нескольких датчиков.

Мастер-программа запустит все подчиненные программы. (в настоящее время я использую fp = popen(./slave1/slave1,"r"); для этого), а затем создаю сегменты разделяемой памяти, к которым может подключиться каждый ведомый. Смысл этого в том, что если умирает раб, он может быть восстановлен мастером и повторно подключен к тому же сегменту общей памяти.
Рабы также могут быть заменены во время работы (например, переключение одного GPS с другим).

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

Высоко ценятся предложения и другие решения проблемы. Ключ должен иметь некоторую форму связи до настройки общей памяти.

Ответы [ 4 ]

1 голос
/ 07 февраля 2011

Возможно, вы захотите взглянуть на SCM_RIGHTS режим передачи доменных сокетов Unix - это позволяет передавать файловый дескриптор через локальный сокет.Это может быть использовано для передачи stderr и тому подобного вашим подчиненным процессам.

Вы также можете передавать сегменты совместно используемой памяти как дескриптор файла (по крайней мере, в Linux).Создайте файл со случайным именем в /dev/shm и немедленно отсоедините его.Теперь ftruncate до нужного размера и mmap с MAP_SHARED.Теперь у вас есть сегмент общей памяти, связанный с дескриптором файла.Одним из приятных моментов этого подхода является то, что сегмент разделяемой памяти автоматически уничтожается, если завершаются все процессы, удерживающие его.

Собрав все это вместе, вы можете передать своим рабам один конец домена unix socketpair().Просто оставьте fd открытым через exec и передайте номер fd в командной строке.Передайте любую конфигурационную информацию, которую вы хотите, как обычные данные, через пару сокетов, затем передайте файловый дескриптор, указывающий на ваш сегмент совместно используемой памяти.

1 голос
/ 07 февраля 2011

Я предлагаю использовать другое средство для общения.Именованные трубы - это то, как я думаю.Перенаправление стандартного out / err будет в лучшем случае непростым делом.

Я предлагаю использовать boost.interprocess для обработки IPC.И будьте внимательны к синхронизации:)

my2c

0 голосов
/ 07 февраля 2011

Трубы не перенаправляются - они идут туда, куда идут, когда они были созданы. То, что вам нужно сделать, это заставить подчиненное устройство закрыть канал, когда это будет сделано с ним, а затем снова открыть свой стандартный вывод в другом месте. Если вы всегда хотите вывод на терминал, вы можете использовать freopen("/dev/tty", "w", stdout), но тогда он всегда будет идти на терминал - вы не сможете перенаправить его куда-либо еще.

0 голосов
/ 07 февраля 2011

Для решения конкретной проблемы отправляйте отладочные сообщения в stderr, а не в stdout.

...