я не понимаю функцию popen.
как трубы могут сообщаться друг с другом?
pipe() : канал является однонаправленным и является буфером потока байтов в ядре. Поскольку это поток байтов, записывающий может записывать произвольное количество байтов, а считыватель может считывать произвольное количество байтов. Однако обратите внимание, что последовательное чтение возможно, но поиск (например, lseek) невозможен. Поскольку канал является однонаправленным, данные, записываемые в канал, должны буферизоваться в ядре до тех пор, пока они не будут прочитаны с конца канала для чтения. Кроме того, если канал заполняется, запись блокируется.
Предположим, что fd — это целочисленный массив из двух файловых дескрипторов (int fd[2]), тогда системный вызов pipe(fd) должен создать канал и вернуть пару файловых дескрипторов, таких что fd[1] (stdout равен 1) должен быть концом канала записи, а fd[0] (stdin равен 0) должен быть концом канала чтения. В отличие от именованного канала (например, FIFO — канала с именем в файловой системе), анонимные каналы могут использоваться только между связанными процессами, такими как родитель-потомок. Таким образом, необходимо выполнить разветвление, чтобы дублировать эти 2 родительских файловых дескриптора в дочернем, тем самым родитель разделяет канал с дочерним, так что дочерний элемент должен писать в конец записи, а родитель должен читать из конца чтения канала, или родитель должен записывать в запись- end и потомок должен читать из read-end канала. Следует позаботиться о том, чтобы неиспользуемый файловый дескриптор чтения (fd[0]) / неиспользуемый файловый дескриптор записи (fd[1]) закрывался родительским или дочерним элементом в соответствии со сценарием.
popen() : popen позволяет вам вызывать другую программу как новый процесс и тем самым передавать ей данные или получать данные от нее. В случае popen обратите внимание, что направление потока данных основано на втором аргументе. Нам не нужно вручную создавать дочерний процесс, так как popen автоматически разветвляется для создания дочернего процесса, запускает оболочку и выполняет аргумент команды, переданный через popen. Он также автоматически устанавливает соответствующий поток чтения или записи между родительским и дочерним элементами на основе аргумента типа.
Таким образом, popen() упрощает работу, поскольку позволяет избежать необходимости вручную вызывать/вызывать pipe, fork, exec и упрощает автоматическое установление соответствующих потоков между родителем/потомком в соответствии с типом аргумента. Однако следует отметить, что другая сторона popen заключается в том, что каждый вызов popen() должен приводить к созданию дополнительного процесса, то есть оболочка вызывается каждый раз, кроме вызываемой программы, которая вызывается. свою очередь приводит к высокому потреблению ресурсов.
person
Karthik Balaguru
schedule
04.11.2015
popen2()
, а не оpopen()
, я думаю. Я также предполагаю, что 2-й блок кода — это функцияpopen2()
. Вы должны обратиться кman 2 pipe
и прочитать описание. Канал представлен двумя файловыми дескрипторами, один для записи и один для чтения. То, что вы пишете в нем, может быть прочитано из него. Послеfork()
один из процессов может писать в него, а другой читать из него, поэтому они взаимодействуют. - person hexasoft   schedule 04.11.2015