Стояла задача породить потомка 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) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в процесс роодитель другой в процесс потомок?!
всё ли верно изложил? что упустил? исправьте/дополните, спасибо.
>Верно ли понимаю происходящее
>1) поле раздвоения процесса в каждом (и родителе и потомке) присутсвует канал
>связи для чтения и записи, можно сказать двухстороньяя трубаэто один и тот же канал.
>2) затем исполняя код родителя if ( pid > 0 ) мы затыкаем один конец трубы предназначеный для записи close(pipedes[1]); и производим чтения из конца трубы "while ((len = read(pipedes[0]" предназначеного для чтения.
>3) в потомке делаем то что и в родителе только наоборот, закрываем
>дескриптор потока для чтения и открываем для записичто написал --- то и делается
>4) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в
>процесс роодитель другой в процесс потомок?!дескрипторы наследуются от родителя к потомкам
>всё ли верно изложил? что упустил? исправьте/дополните, спасибо.почитай конспект, лектор там наверно изложил именно то, что быдет спрашивать на экзамене ;)
>[оверквотинг удален]
>
>что написал --- то и делается
>>4) каким образом эти два "конца" трубы чтение/запись оказываются "воткнутыми" один в
>>процесс роодитель другой в процесс потомок?!
>
>дескрипторы наследуются от родителя к потомкам
>>всё ли верно изложил? что упустил? исправьте/дополните, спасибо.
>
>почитай конспект, лектор там наверно изложил именно то, что быдет спрашивать на
>экзамене ;)мне интересно выучить, экзамен шелуха.
>Верно ли понимаю происходящее
>1) поле раздвоения процесса в каждом (и родителе и потомке) присутсвует канал
>связи для чтения и записи, можно сказать двухстороньяя труба
>это один и тот же канал.КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же канал" получается что канал дублируется и что родитель что потомок содержат собственные копии, но как тогда происходит подача из одного конца трубы из потомка в конец другой трубы родителя!?
>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>канал" получается что канал дублируется и что родитель что потомок содержат
>собственные копии, но как тогда происходит подача из одного конца трубы
>из потомка в конец другой трубы родителя!?У трубы два конца. До форка оба лежат в одном процессе. После форка каждый пишет только в один конец трубы, а второй закрывает.
>>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>>канал" получается что канал дублируется и что родитель что потомок содержат
>>собственные копии, но как тогда происходит подача из одного конца трубы
>>из потомка в конец другой трубы родителя!?
>
>У трубы два конца. До форка оба лежат в одном процессе. После
>форка каждый пишет только в один конец трубы, а второй закрывает.
>но закрыли то мы самостоятельно, или если не закрывать один конец трубы то связи меж родственными процессами посредством трубопровода не будет?
>но закрыли то мы самостоятельно, или если не закрывать один конец трубы
>то связи меж родственными процессами посредством трубопровода не будет?Будет даже если не закроешь.
В принципе, можно и несколькими процессами в один поток писать, только вот ерунда получится :)
>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>канал" получается что канал дублируется и что родитель что потомок содержат
>собственные копии, но как тогда происходит подача из одного конца трубы
>из потомка в конец другой трубы родителя!?Канал не дублируется и никаких копий его не создаётся. Канал - это объект ядра, то есть он есть не в процессе, а в ядре. Процесс может к нему обращаться. Ссылки на него (файловые дескрипторы) действительны в обоих процессах: и в родительском, и в дочернем. Так они и обращаются к одной и той же трубе.
>>КАКИМ тогда образом происходит общение РАЗНЫХ процессов через "один и тот же
>>канал" получается что канал дублируется и что родитель что потомок содержат
>>собственные копии, но как тогда происходит подача из одного конца трубы
>>из потомка в конец другой трубы родителя!?
>
>Канал не дублируется и никаких копий его не создаётся. Канал - это
>объект ядра, то есть он есть не в процессе, а в
>ядре. Процесс может к нему обращаться. Ссылки на него (файловые дескрипторы)
>действительны в обоих процессах: и в родительском, и в дочернем. Так
>они и обращаются к одной и той же трубе.Понял, Спасибо.
Полседний вопрос, каким образом из потомка послать родителю СИГНАЛ TERM для завершения работы программы?
>Полседний вопрос, каким образом из потомка послать родителю СИГНАЛ TERM для завершения
>работы программы?Узнать PID родителя и использовать kill().
Хотя это выглядит криво, лучше завершить потомка с соответствующим кодом возврата, а в родителе это соответственно обработать.
не вникну каким образом вместо исполняемой программы прописаной статично указать программу переданую с консоли, планаexecve("usr/bin/cat", argv, NULL);
execve(argv[1], argv, NULL); - не работает
> execve("usr/bin/cat", argv, NULL);
>execve(argv[1], argv, NULL); - не работаетВы не догадываетесь, что usr/bin/cat все еще остается в argv, который вы передаете usr/bin/cat? Ну и вообще argv в сях имеет в себе такую глупость, как имя самой программы в argv[0], вместо вынесения его в отдельную переменную.