Межпроцессное взаимодействие в языке Си, по одному символу за раз
Во-первых, это домашнее задание, я не прошу ответа, однако я в чем-то запутался.
У меня есть домашнее задание для класса программирования, и я немного запутался в том, как написать код определенным способом, который просит преподаватель.
Программа сначала создает дочерний процесс, а затем переходит к передаче аргументов командной строки из родительского процесса по каналу, по одному символу в дочерний процесс, а затем считывает их в дочерний процесс по одному символу за раз, увеличивая количество символов в дочернем процессе каждый раз, когда символ считывается.
Я думаю, что мне удалось отправить данные по каналу по одному символу за раз, но я понятия не имею, как "перейти" к дочернему процессу каждый раз, когда отправляется символ, прочитать его, увеличить количество символов, а затем вернуться к родительскому процессу и повторить.Вот мой код, он работает и дает точные ответы, но никаких советов о том, как выполнить то, что мой инструктор просит, будет оценено, спасибо!!
// 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 ответа:
Вам необходимо внести следующие изменения:
Сделайте последний аргумент 1 в вызове
read
.read(pA[0], buff, 1);
Поместите вышеупомянутый вызов в цикл while и увеличивайте
nChar
для каждой успешной попыткиread
.while ( read(pA[0], buff, 1) == 1 ) { ++nChars; }
Закройте дескриптор файла из родительского процесса, как только вы закончите запись в него.
Вот рабочая версия
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; } }