Межпроцессное взаимодействие в языке Си, по одному символу за раз


Во-первых, это домашнее задание, я не прошу ответа, однако я в чем-то запутался.

У меня есть домашнее задание для класса программирования, и я немного запутался в том, как написать код определенным способом, который просит преподаватель.

Программа сначала создает дочерний процесс, а затем переходит к передаче аргументов командной строки из родительского процесса по каналу, по одному символу в дочерний процесс, а затем считывает их в дочерний процесс по одному символу за раз, увеличивая количество символов в дочернем процессе каждый раз, когда символ считывается.

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

Вот мой код, он работает и дает точные ответы, но никаких советов о том, как выполнить то, что мой инструктор просит, будет оценено, спасибо!!

// Characters from command line arguments are sent to child process
// from parent process one at a time through pipe.
//
// Child process counts number of characters sent through pipe.
//
// Child process returns number of characters counted to parent process.
//
// Parent process prints number of characters counted by child process.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char **argv)
{
// set up pipe

    int    pA[2];
char   buff[50];

pipe(pA);
// call fork()

pid_t  childId = fork();

if (childId == 0) {
    // -- running in child process --
    int     nChars = 0;

    // close the output side of pipe
    close(pA[1]);

    // Receive characters from parent process via pipe
    // one at a time, and count them.

    nChars = read(pA[0], buff, sizeof(buff)); //this line of code is what i need to change to be reading characters in one at a time

    // Return number of characters counted to parent process.
    return nChars;
    }
else {
    // -- running in parent process --
    int     nChars = 0;
    int     size = 0;
    printf("CS201 - Assignment 3 - Timothy Jensenn");

    // close the input side of the pipe
    close(pA[0]);

    // Send characters from command line arguments starting with
    // argv[1] one at a time through pipe to child process.

    for (int i = 1; i < argc; i++)
      {
        size = strlen(argv[i]);
        for (int z = 0; z < size; z++)
          {
        write(pA[1], &argv[i][z], 1);
          }
      }

    // Wait for child process to return. Reap child process.
    // Receive number of characters counted via the value
    // returned when the child process is reaped.

    wait(&nChars);

    printf("child counted %d charsn", nChars/256);
    return 0;
    }
}
2 2

2 ответа:

Вам необходимо внести следующие изменения:

  1. Сделайте последний аргумент 1 в вызове read.

    read(pA[0], buff, 1);
    
  2. Поместите вышеупомянутый вызов в цикл while и увеличивайте nChar для каждой успешной попытки read.

       while ( read(pA[0], buff, 1) == 1 )
       {
          ++nChars;
       }
    
  3. Закройте дескриптор файла из родительского процесса, как только вы закончите запись в него.

Вот рабочая версия main.

int main(int argc, char **argv)
{
   // set up pipe

   int    pA[2];
   char   buff[50];

   pipe(pA);
   // call fork()

   pid_t  childId = fork();

   if (childId == 0) {
       // -- running in child process --
       int     nChars = 0;

       // close the output side of pipe
       close(pA[1]);

       // Receive characters from parent process via pipe
       // one at a time, and count them.
       while ( read(pA[0], buff, 1) == 1 )
       {
          ++nChars;
       }

       return nChars;
   }
   else {
       // -- running in parent process --
       int     nChars = 0;
       int     size = 0;
       printf("CS201 - Assignment 3 - Timothy Jensen\n");

       // close the input side of the pipe
       close(pA[0]);

       // Send characters from command line arguments starting with
       // argv[1] one at a time through pipe to child process.

       for (int i = 1; i < argc; i++)
       {
          size = strlen(argv[i]);
          for (int z = 0; z < size; z++)
          {
             write(pA[1], &argv[i][z], 1);
          }
       }

       close(pA[1]);

       // Wait for child process to return. Reap child process.
       // Receive number of characters counted via the value
       // returned when the child process is reaped.

       wait(&nChars);

       printf("child counted %d chars\n", nChars/256);
       return 0;
   }
}

Это кажется немного глупым, но вы могли бы изменить:

nChars = read(pA[0], buff, sizeof(buff)); 

Кому:

char ch;
nChars = read(pA[0], &ch, 1); 

Конечно, вы могли бы поместить вышесказанное в цикл, чтобы собрать строку "один символ за раз" обратно в buff.