Поскольку я не верю в то, чтобы делать для них работу людей, Я не могу дать вам «решение». Я могу, однако, показать вам некоторые из понятий, которые вам нужно знать, чтобы выполнить свое задание. Я также могу дать вам пару ссылок, но если вы просто ищите помощь с концепциями, которые вы не понимаете, вы, скорее всего, найдете необходимую информацию.
Теперь, когда я представил абзац вводной информации, я собираюсь проработать некоторые из понятий, которые вам нужно понять, чтобы решить эту проблему.
Я могу заполнить недостающую информацию, если я получу (и чувствую, что стоит потратить) время, необходимое, чтобы превратить это в псевдо-учебник. :)
Предоставленная информация может быть упрощена, немного расплывчата или открыта для улучшения. Не стесняйтесь, дайте мне знать, если вы, дорогой читатель, обнаружите проблему.
Первая концепция: вилка() - Инж
Что это?fork()
позволяет легко выполнять несколько операций одновременно, дублируя (большую часть) текущего процесса в другой процесс. (На самом деле, это похоже на asexual reproduction.)
Например, ребенка процесс (это новый процесс, который был создан, делая fork()
системный вызов) наследует описатели файла (это важный момент!), имеет свою собственную копию переменных, которые родительский процесс (имеет/имел) и т. д.
Пример: Вот пример программы, иллюстрирующей вещь или две. Обратите внимание на wait()
. Это делает родительский процесс, который вызвал fork()
, ждет, чтобы продолжить выполнение оставшейся части программы до тех пор, пока ребенок не завершится. Без wait(NULL)
мы не можем гарантировать, что инструкция родителя printf
будет запущена после инструкции printf
ребенка.
#include <stdio.h> //the usual, perror
#include <stdlib.h> //exit
#include <sys/types.h> //wait()/pid_t
#include <sys/wait.h> //wait()
#include <unistd.h> // fork()
int main() {
pid_t cpid;
//create our child.
//fork() returns -1 if the fork failed, otherwise it returns
// the pid of the child to the parent,
// and 0 to the child
cpid = fork();
//Both the child process and parent process executed the
//"cpid =" assignment.
//However, they both modified their own version of cpid.
//From now on, everything is run by both the child and parent.
//the fork failed; there is no child so we're done.
if (cpid < 0) {
perror("During attempted fork");
exit(EXIT_FAILURE);
}
//Though the if statement will be checked by both,
//cpid will equal 0 only in the child process.
if (cpid == 0) {
//This will be executed by the child.
printf("Hello. I'm your child.\n");
//Now that we've let Pops know that we're alive...
exit(EXIT_SUCCESS);
}
else if (cpid > 0) {
//wait for our child to terminate.
//I dare you to comment this out & run the program a few times.
//Does the parent ever print before the child?
wait(NULL);
printf("I proudly parented 1 child.\n");
}
return 0;
}
Другое: Вы можете увидеть еще один пример here.
Вторая концепция: Трубы
Что такое труба? Труба - это метод межпроцессного взаимодействия. В принципе, у него есть один конец для ввода данных (write()
- один из способов сделать это) и один конец, из которого можно получить данные (используя read
).
Трубы создаются с использованием системного вызова pipe()
. Он возвращает -1 при ошибке. Это только аргумент - это адрес массива из двух ints, который мы назовем pipe_fds
.
Если вызов преуспел, первый элемент в pipe_fds
содержит file descriptor
, который используется для чтения из трубы; второй элемент содержит file descriptor
, используемый для записи в трубу.
Вы можете написать на трубу с write()
и прочитать с трубы read()
. (Более подробную информацию об использовании труб можно найти на various places на the internet.
Вот пример:
#include <stdio.h> //the usual, perror
#include <stdlib.h> //exit
#include <sys/types.h> //wait()/pid_t
#include <sys/wait.h> //wait()
#include <unistd.h> // fork(), pipe()
#define BUFLEN 256 //must be greater than one
int main() {
int pipe_fds[2],
pipe_ret;
pid_t cpid;
//Let's create a pipe.
//Note that we do this *before* forking so that our forked child
// has access to the pipe's file descriptors, pipe_fds.
pipe_ret = pipe(pipe_fds);
//we couldn't create our pipe
if (pipe_ret == -1) {
perror("Pipe Creation");
exit(EXIT_FAILURE);
}
//create our child.
cpid = fork();
//the fork failed; there is no child so we're done.
if (cpid < 0) {
perror("During attempted fork");
exit(EXIT_FAILURE);
}
//Am I the child?
if (cpid == 0) {
//close the childs read end of the pipe.
//Failing to close unused pipe ends is life or death!
//(Check `man 7 pipe`)
close(pipe_fds[0]);
//Send a message through the pipe.
//NOTE: For simplicity's sake, we assume that our printing works.
// In the real world, it might not write everything, etc.
//We could use `write()`, but this way is easier.
dprintf(pipe_fds[1], "Daddy, I'm alive.\n");
//We're done writing. Close write end of the pipe.
//This is the wise thing to do, but it would get closed anyways.
close(pipe_fds[1]);
//Now that we've let Pops know that we're alive...
exit(EXIT_SUCCESS);
}
else if (cpid > 0) {
char buf[BUFLEN] = {};
int bytes_read = 0;
//close *our* write end of the pipe. Important!
//Comment this out and watch your program hang.
//Again, check out `man 7 pipe`.
close(pipe_fds[1]);
//read data from pipe until we reach EOF
while ((bytes_read = read(pipe_fds[0], buf, BUFLEN - 1)) > 0) {
//null terminate our string.
//(We could use snprintf instead...)
buf[bytes_read] = '\0';
//You can comment this out to prove to yourself that
//we're the one printing the child's message.
printf("%s", buf);
}
//close read end of pipe
close(pipe_fds[0]);
//wait for our child to terminate.
wait(NULL);
printf("I proudly parented 1 child.\n");
}
return 0;
}
Как вы можете видеть, я просто дал небольшой учебник на двух понятий вы нужно знать, чтобы закончить ваше задание. Мне нужно немного поспать, поэтому я оставлю его на этом сегодня вечером.
Читайте и экспериментируйте с примерами. Примечания в комментариях помогут вам узнать.
Этот сайт специально для вопросов, а не для общего совета или помощи. –
Если вы используете ОС на базе Linux, проверьте 'man pipe',' man fork' и т. Д. –
Конечно, если вы используете функцию 'fork', я могу с уверенностью предположить, что вы не программируете на окна. :) (Да, я знаю, что есть Cygwin ...) –