The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Общение 'родных' процессов через неименованый каналы связи"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 27-Май-09, 23:09 
Стояла задача породить потомка fork который в своём теле вызовит exec* и выполнив программу, её результат вернёт процессу родителю. Другими словами организовать общение между родителем и потомком посредством неименованого канала связи.

родил код:
[C]
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#define BUF_SIZE 80

int main (int argc, char * argv[])
{

  int pipedes[2]; //массив для хранения дескрипторов чтения запсиси неименованого канала связи
  pid_t pid; //принимает участие при создании потомков


/*
pipe создает пару файловых описателей, указывающих на запись inode именованного канала, и помещает их в массив, на который указывает filedes. filedes[0] предназначен для чтения, а filedes[1] предназначен для записи.  
*/
  pipe(pipedes);

/*
fork создает процесс-потомок, который отличается от родительского только значениями PID (идентификатор процесса) и PPID (идентификатор родительского процесса), а также тем фактом, что счетчики использования ресурсов установлены в 0. Блокировки файлов и сигналы, ожидающие обработки, не наследуются.
*/
  pid = fork();


//если это процесс родитель;
  if ( pid > 0 )
  {
    char buf[BUF_SIZE];
    int len;
//закроем поток предназначеный для для записи
    close(pipedes[1]);

//читаем из потока  
    while ((len = read(pipedes[0], buf, BUF_SIZE)) > 0)
      write(1, buf, len);
    close(pipedes[0]);
  }


//если это процесс потомок;
  else
  {
//закрыть поток предназначеный для чтения
    close(pipedes[0]);

/*
dup и dup2 создают копию файлового дескриптора oldfd.
Старый и новый дескрипторы можно использовать друг вместо друга.
Они имеют общие блокировки, указатель позиции в файле и флаги;
например, если позиция в файле была изменена с помощью lseek,
на одном из дескрипторов, то эта позиция также меняется и на втором.
Два дескриптора, однако, каждый имеют свой собственный флаг закрыть-при-exec.
*/
    dup2(pipedes[1], 1);


//выолним программу
    execve("/bin/cat", argv, NULL);
  }

  return 0;
}    

[/C]
Верно ли понимаю происходящее

1) поле раздвоения процесса в каждом (и родителе и потомке) присутсвует канал связи для чтения и записи, можно сказать двухстороньяя труба

2) затем исполняя код родителя if ( pid > 0 )    мы затыкаем один конец трубы предназначеный для записи  close(pipedes[1]); и производим чтения из конца трубы "while ((len = read(pipedes[0]" предназначеного для чтения.

3) в потомке делаем то что и в родителе только наоборот, закрываем дескриптор потока для чтения и открываем для записи

4) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в процесс роодитель другой в процесс потомок?!

всё ли верно изложил? что упустил? исправьте/дополните, спасибо.
    

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от gaa (ok) on 27-Май-09, 23:46 
>Верно ли понимаю происходящее
>1) поле раздвоения процесса в каждом (и родителе и потомке) присутсвует канал
>связи для чтения и записи, можно сказать двухстороньяя труба

это один и тот же канал.
>2) затем исполняя код родителя if ( pid > 0 )    мы затыкаем один конец трубы предназначеный для записи  close(pipedes[1]); и производим чтения из конца трубы "while ((len = read(pipedes[0]" предназначеного для чтения.
>3) в потомке делаем то что и в родителе только наоборот, закрываем
>дескриптор потока для чтения и открываем для записи

что написал --- то и делается
>4) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в
>процесс роодитель другой в процесс потомок?!

дескрипторы наследуются от родителя к потомкам
>всё ли верно изложил? что упустил? исправьте/дополните, спасибо.

почитай конспект, лектор там наверно изложил именно то, что быдет спрашивать на экзамене ;)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 28-Май-09, 09:44 
>[оверквотинг удален]
>
>что написал --- то и делается
>>4) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в
>>процесс роодитель другой в процесс потомок?!
>
>дескрипторы наследуются от родителя к потомкам
>>всё ли верно изложил? что упустил? исправьте/дополните, спасибо.
>
>почитай конспект, лектор там наверно изложил именно то, что быдет спрашивать на
>экзамене ;)

мне интересно выучить, экзамен шелуха.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 28-Май-09, 09:52 
>Верно ли понимаю происходящее
>1) поле раздвоения процесса в каждом (и родителе и потомке) присутсвует канал
>связи для чтения и записи, можно сказать двухстороньяя труба
>это один и тот же канал.

КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же канал" получается что канал дублируется и что родитель что потомок содержат собственные копии, но как тогда происходит подача из одного конца трубы из потомка в конец другой трубы родителя!?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от gaa (ok) on 28-Май-09, 12:21 
>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>канал" получается что канал дублируется и что родитель что потомок содержат
>собственные копии, но как тогда происходит подача из одного конца трубы
>из потомка в конец другой трубы родителя!?

У трубы два конца. До форка оба лежат в одном процессе. После форка каждый пишет только в один конец трубы, а второй закрывает.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 28-Май-09, 15:38 
>>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>>канал" получается что канал дублируется и что родитель что потомок содержат
>>собственные копии, но как тогда происходит подача из одного конца трубы
>>из потомка в конец другой трубы родителя!?
>
>У трубы два конца. До форка оба лежат в одном процессе. После
>форка каждый пишет только в один конец трубы, а второй закрывает.
>

но закрыли то мы самостоятельно, или если не закрывать один конец трубы то связи меж родственными процессами посредством трубопровода не будет?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от gaa (ok) on 28-Май-09, 16:34 
>но закрыли то мы самостоятельно, или если не закрывать один конец трубы
>то связи меж родственными процессами посредством трубопровода не будет?

Будет даже если не закроешь.
В принципе, можно и несколькими процессами в один поток писать, только вот ерунда получится :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от jd (??) on 28-Май-09, 19:59 
>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>канал" получается что канал дублируется и что родитель что потомок содержат
>собственные копии, но как тогда происходит подача из одного конца трубы
>из потомка в конец другой трубы родителя!?

Канал не дублируется и никаких копий его не создаётся. Канал - это объект ядра, то есть он есть не в процессе, а в ядре. Процесс может к нему обращаться. Ссылки на него (файловые дескрипторы) действительны в обоих процессах: и в родительском, и в дочернем. Так они и обращаются к одной и той же трубе.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 28-Май-09, 20:56 
>>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>>канал" получается что канал дублируется и что родитель что потомок содержат
>>собственные копии, но как тогда происходит подача из одного конца трубы
>>из потомка в конец другой трубы родителя!?
>
>Канал не дублируется и никаких копий его не создаётся. Канал - это
>объект ядра, то есть он есть не в процессе, а в
>ядре. Процесс может к нему обращаться. Ссылки на него (файловые дескрипторы)
>действительны в обоих процессах: и в родительском, и в дочернем. Так
>они и обращаются к одной и той же трубе.

Понял, Спасибо.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 28-Май-09, 21:59 
Полседний вопрос, каким образом из потомка послать родителю СИГНАЛ TERM для завершения работы программы?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от gaa (ok) on 28-Май-09, 23:29 
>Полседний вопрос, каким образом из потомка послать родителю СИГНАЛ TERM для завершения
>работы программы?

Узнать PID родителя и использовать kill().

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от freelan (ok) on 29-Май-09, 15:59 
не вникну каким образом вместо исполняемой программы прописаной статично указать программу переданую с консоли, плана  

  execve("usr/bin/cat", argv, NULL);

execve(argv[1], argv, NULL); - не работает
    

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Общение 'родных' процессов через неименованый каналы связи"  +/
Сообщение от angra (ok) on 31-Май-09, 08:06 
>  execve("usr/bin/cat", argv, NULL);
>execve(argv[1], argv, NULL); - не работает

Вы не догадываетесь, что usr/bin/cat все еще остается в argv, который вы передаете usr/bin/cat? Ну и вообще argv в сях имеет в себе такую глупость, как имя самой программы в argv[0], вместо вынесения его в отдельную переменную.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру