Не получить все строки из трубы

Я работаю над заданием, в котором мне нужно несколько процессов (родитель и дети) для общения.
Родитель отправляет пути к файлам детям, и они должны запустить Linux file (/ usr / bin / file) на них, возвращая вывод отцу.

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

Я собираюсь отправить несколько путей к файлам каждому ребенку (пакет файлов), а затем прочитать fileвыходной.

Эта проблема:

Я использую цикл для write несколько путей к файлам, но когда я read выходной канал ребенка Я не получаю весь вывод, который я должен.

Код:

#define Read            0
#define Write           1
#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]
#define PIPE_BUF_LEN    4096

using namespace std;
int main()
{
/** Pipe for reading for subprocess */
int read_pipe[2];
/** Pipe for writing to subprocess */
int write_pipe[2];
char buffer[PIPE_BUF_LEN] = "";
if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
{
pid_t pid = fork();
if (pid == -1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
else if (pid == 0) //Child process
{
close(ParentRead);
close(ParentWrite);
dup2 (ChildRead, STDIN_FILENO); /*redirect ChildRead to stdin*/
dup2 (ChildWrite, STDOUT_FILENO); /*redirect stdout to ChildWrite*/
char* paramArgs[]={"/usr/bin/file","-n","-f-",NULL};
execv("/usr/bin/file",paramArgs);
exit(EXIT_FAILURE);
}
else { //Parent process
close(ChildRead);
close(ChildWrite);

for (int i=0; i < 3 ;i++)
{
/*write to processes which are ready for writing: */
fd_set rfds;
int retval;
FD_ZERO(&rfds);
FD_SET(ParentWrite, &rfds);
retval = select(10, NULL, &rfds, NULL, NULL);
if (retval == -1)
{
perror("select()");
}
else if (retval)
{
write(ParentWrite, "file1\nfile2\n", 12);
}
/*read from processes which are ready for reading*/
FD_ZERO(&rfds);
FD_SET(ParentRead, &rfds);
retval = select(10, &rfds, NULL, NULL, NULL);
if (retval == -1)
{
perror("select()");
}
else if (retval)
{
read(ParentRead, buffer, PIPE_BUF_LEN);
cout << buffer;
}
}
}
}
exit(EXIT_SUCCESS);
}

В этом случае я пытаюсь запустить file в «file1 \ nfile2 \ n» (обратите внимание на используемые -n -f- flags) в цикле из трех итераций, ожидая получить шесть строк, но получить только три:

file1: ERROR: невозможно открыть `file1 ‘(нет такого файла или каталога)

file2: ERROR: невозможно открыть `file2 ‘(нет такого файла или каталога)

file1: ERROR: невозможно открыть `file1 ‘(нет такого файла или каталога)

Когда я не перенаправляю вывод дочернего объекта в канал (позволяя записать его в std_out), я получаю все шесть строк.

Любая помощь будет оценена.

0

Решение

Планировщик Вы находитесь в цикле, который спрашивает ребенка (то есть, PGM file) посмотреть два файла три раза. Вы делаете только одно чтение за цикл в родительском.

  • Если дочерний процесс запланирован и непрерывен, он выполняет поиск первого файла, записывает канал, выполняет второй поиск, записывает в канал. Родитель получает расписание, и вы читаете весь вывод ребенка за одно чтение. Ты золотой (но везучий).
  • Ребенок запланирован, делает первый поиск и запись в канал и прерывается. Родитель читает один вывод. Ребенок перераспределяется, выполняет второй поиск и записывает канал. Родитель читает один вывод. Поскольку вы читаете только 3 раза, вы читаете только 3 из 6 выходов.
  • Вариации на вышесказанное. Может быть, вы прочитаете 1 вывод, затем 3, затем 1. Вы просто не знаете.

Обратите внимание, что причина, по которой вы, по крайней мере, получаете полный дочерний вывод при каждом чтении, заключается в том, что конвейерные записи гарантированно будут атомарными, если они имеют длину PIPE_BUF. Если вы использовали такую ​​подпрограмму, скажем, в сокете, вы можете получить некоторую дробную часть сообщения при каждом чтении.

Решение: Вы должны читать в цикле, пока не получите ожидаемое количество байтов (или полное сообщение). В этом случае я предполагаю вывод file всегда одна строка, заканчивающаяся символом новой строки. Но вы просите двух file выводит каждый раз через цикл. Так что читайте, пока не будет выполнено это условие, а именно, пока вы не прочитаете две полные строки.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]