четная нечетная программа с использованием fork - PullRequest
0 голосов
/ 16 июня 2020

Я пишу программу для четных и нечетных чисел, используя вилку, которая иногда печатает четные, а иногда и нечетные. Пожалуйста, объясните эту проблему?

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
        int i;
        if(fork() == 0)
        {
                for(i=1;i<50;i++)
                        if(i%2 == 0)
                                printf("even %d\n",i);
        }
        else
        {
                for(i=1;i<50;i++)
                        if(i%2 != 0)
                                printf("odd %d\n",i);
        }
}

Я получаю результат, как показано ниже: нечетный 1 нечетный 3 нечетный 5 нечетных 7 нечетных 9 нечетных 11 нечетных 13 нечетных 15 нечетных 17 нечетных 19 нечетных 21 нечетных 23 нечетных 25 четных 2 нечетных 27 четных 4 нечетных 29 четных 6 нечетных 31 четных 8 нечетных 33 четных 10 нечетных 35 четных 12 нечетных 37 четных 14 нечетных 39 четных 16 нечетных 41 четных 18 нечетных 43 четных 20 нечетных 45 четных 22 нечетных 47 четных 24 нечетных 49 четных 26 четных 28 четных 30 четных 32 четных 34 четных 36 четных 38 четных 40 четных 42 четных 44 четных 46 четных 48

Ответы [ 2 ]

0 голосов
/ 16 июня 2020

После успешного fork() родительский и дочерний процессы будут выполняться практически одновременно. (Как указывает другой ответ, это реализуется путем быстрого переключения контекста между ними.) Выходные данные этих процессов могут поступать в выходной поток в любое время.

Комментарий, приложенный к вопросу, предполагает, что ожидание было чтобы дочерний процесс завершил свое for l oop до того, как родительский процесс начнет выполнять свой собственный for l oop. Для этого должен быть выполнен явный вызов wait или waitpid. Это приведет к блокировке родительского процесса, пока дочерний процесс не выйдет.

В измененном коде ниже показано включение вызова waitpid. См. Также вывод ниже, содержащий все четные числа перед нечетными.

Другие примечания:

  • Вывод printf подлежит буферизации stdio, но здесь нет необходимости явно вызывать fflush, чтобы гарантировать, что четные числа полностью записаны перед нечетными, потому что это будет сделано автоматически перед выходом дочернего элемента.

  • Вызывая waitpid, родительский элемент также собирает статус выхода дочернего элемента через указатель int *, который передается в качестве второго аргумента. В коде вопроса wait или waitpid никогда не вызываются. Таким образом, если дочерний элемент выйдет раньше родителя, его статус выхода будет сохранен в таблице процессов (как процесс «зомб ie») до тех пор, пока родитель не выйдет. В этом примере родительский и дочерний процессы завершат sh примерно в одно и то же время, но в целом рекомендуется убедиться, что родительский процесс, который порождает дочерний процесс, выполняет последующий вызов ожидания (или выполняет signal(SIGCHLD, SIG_IGN); для указать ядру, что статус выхода дочернего элемента не требуется).

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

int main()
{
  int i, status;
  pid_t pid;

  pid = fork();
  if (pid == 0)
    {
      for(i=1;i<50;i++)
        if(i%2 == 0)
          printf("even %d\n",i);
    }
  else
    {
      if (pid > 0)
        pid = waitpid(pid, &status, 0);
      for(i=1;i<50;i++)
        if(i%2 != 0)
          printf("odd %d\n",i);
    }
  return 0;
}

Вывод:

even 2
even 4
even 6
even 8
even 10
even 12
even 14
even 16
even 18
even 20
even 22
even 24
even 26
even 28
even 30
even 32
even 34
even 36
even 38
even 40
even 42
even 44
even 46
even 48
odd 1
odd 3
odd 5
odd 7
odd 9
odd 11
odd 13
odd 15
odd 17
odd 19
odd 21
odd 23
odd 25
odd 27
odd 29
odd 31
odd 33
odd 35
odd 37
odd 39
odd 41
odd 43
odd 45
odd 47
odd 49
0 голосов
/ 16 июня 2020

После fork() будет создан дочерний процесс.

Дочерний процесс получил возвращаемое значение 0 и будет печатать четные числа, в то время как родительский процесс получил идентификатор процесса дочернего процесса в качестве возвращаемого значения fork(), и будет печатать нечетные числа.

        int i;
        if(fork() == 0)
        {
                for(i=1;i<50;i++)
                        if(i%2 == 0)
                                printf("even %d\n",i);
        }
        else
        {
                for(i=1;i<50;i++)
                        if(i%2 != 0)
                                printf("odd %d\n",i);
        }

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

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

Планирование ЦП - это метод определения того, какой процесс запускать в определенный момент времени. И обычно у процесса просто есть короткое время для запуска, прежде чем он будет прерван, а затем задержится там до следующего раза, когда он получит ресурсы. человек, вы не могли почувствовать, что процесс продолжается, когда другой процесс запущен. Это похоже на то, как каждый процесс выполняется одновременно.

Возвращаясь к вашей проблеме, некоторые четные числа печатаются перед odd 49. Например, там odd 25 even 2, это означает, что родительский процесс (который хочет напечатать нечетные числа) был прерван после вывода odd 25. Затем дочерний процесс получил ресурс и распечатал even 2 после этого.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...