LINUX.ORG.RU

Обмен данными между процессами с помощью pipe

 , , ,


0

2

Здравствуйте.
Такая ситуация: есть родительский процесс (Р), который порождает дочерний (C), и потом еще неопределенное количество процессов (C0 - CN)

Нужно как-то синхронизировать данные между C и C0-CN, а точнее, сделать так, чтобы сообщение принимаемое от C0 пересылалось всем C1-CN, и так для каждого CN.

Я решил использовать трубы, но уже сомневаюсь в верности своего решения...
Как я предполагаю, работать это должно так:
1) Родительский процесс создает 2 пайпа, один для сообщений(mp), второй для fd пайпов дочерних процессов(fdp), передает оба дескриптора в C и любой из порожденных CN
2) C0-СN порождаются, создают каждый по новому пайпу pN, отправляют дескриптор pN по fdp, плюс уникальный id
3) С принимает дескрипторы пайпов, сохраняет себе, ассоциирует с id
4) СN отправляет сообщение по mp, C его принимает и отправляет всем СX, с отличным от CN id

Собственно вопрос: я творю какую-то ересь, или мне кажется?
Если не кажется, как сделать проще?
Если кажется, как в C принимать данные из двух пайпов асинхронно - насколько я понял, после вызова read процесс блокируется до записи в пайп с другой стороны.

А кто создаёт дочерние процессы? Если только самый главный, то fork() в родительском процессе как раз возвращает ID нового процесса (а внутри дочернего процесса возвращает 0), так что городить огород не имеет смысла. Или же дети потом ещё самостоятельно могут плодиться?

KivApple ★★★★★ ()
Ответ на: комментарий от KivApple

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

mersinvald ★★★★★ ()

Собственно вопрос: я творю какую-то ересь, или мне кажется?

Да, ересь. Пайпы можно создавать сразу в родительском процессе и использрвать их после fork(), не нужно ничего пересылать между процессами. Либо можно использовать stdint и stdout дочерних процессов для коммуникации с ними, есть и другие варианты с пайпами. Есть ещё варианты с библиотеками вродe zeromq если не хочется заморачиваться блокировками с записью и чтением.

mashina ★★★★★ ()
Ответ на: комментарий от mashina

Окей, так даже проще - уникальный ID будет просто PIDом
Можно поподробнее про stdin stdout?

Если с пайпами не ересь, то все равно остается открытым вопрос с блокировкой read. Мне надо то же самое, но чтобы при чтении, если pipe пуст, процесс не ждал наполнения, а просто продолжал работу.

mersinvald ★★★★★ ()
Ответ на: комментарий от mersinvald

Можно поподробнее про stdin stdout?

Что тут подробнее можно сказать? В обычном варианте создаёшь пару пайов руками перед fork (см. man 2 pipe), а можешь не создават и пользоваться уже существующими stdin и stdout дочернего процесса. Это очень хорошо подходит если протокол обмена будет текстовым, т.е. можно будет дочерние процессы отлаживать прямо руками. Но и для бинарного варианта тоже может пригодиться.

Если с пайпами не ересь, то все равно остается открытым вопрос с блокировкой read.

Естественно, с пайпами или сокетами нужно будет самому разруливать блкировки, т.е. переводить fd в неблокирующий режим и городить свои миниатюрные event-driven обёрки и в дочернем порцессе, и в коммутаторе. Или быть может можно воспользоваться libev{ent}.

mashina ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.