Создание нескольких процессов и симуляций в C с помощью fork () - PullRequest
1 голос
/ 30 апреля 2010

Я хочу создать несколько групп процессов, которые будут вызывать различные функции.

я пишу код ниже. во-первых, я хочу получить следующий вывод

. / Вилка 4 5

 I am a child: 1 PID: 22330
 I am a child2: 1 PID: 22334
 I am a child: 2 PID: 22331
 I am a child2: 5 PID: 22338
 I am a child: 4 PID: 22333
 I am a child: 3 PID: 22332
 I am a child2: 2 PID: 22335
 I am a child2: 4 PID: 22337
 I am a child2: 3 PID: 22336

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void forkChildren (int nChildren) {
     int i;
     pid_t pid;
     for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
          /* error handling here, if needed */
        return;
        }
        if (pid == 0) {
           printf("I am a child: %d PID: %d\n",i, getpid());
           sleep (5);
        wait(NULL);
        return;
        }
     }
  }
 void forkChildren2 (int nChildren) {
      int i;
      pid_t pid;
      for (i = 1; i <= nChildren; i++) {
          pid = fork();
          if (pid == -1) {
            /* error handling here, if needed */
          return;
          }
          if (pid == 0) {
             printf("I am a child2: %d PID: %d\n",i, getpid());
             sleep (2);
             return;
          }
       }
   }

   int main (int argc, char *argv[]) {

      forkChildren (atoi (argv[1]));
      forkChildren2 (atoi (argv[2]));

     return 0;
  }

код дает мне вывод

[ozdeny@hyperion ~]$ ./fork 4 5
I am a child: 1 PID: 22330
I am a child: 2 PID: 22331 
I am a child: 3 PID: 22332 
I am a child: 4 PID: 22333
I am a child2: 1 PID: 22334 
I am a child2: 2 PID: 22335
I am a child2: 4 PID: 22337 
I am a child2: 5 PID: 22338
[ozdeny@hyperion ~]$ I am a child2: 3 PID: 22336
I am a child2: 1 PID: 22339
I am a child2: 2 PID: 22340
I am a child2: 3 PID: 22341
I am a child2: 4 PID: 22342 
I am a child2: 5 PID: 22343
I am a child2: 1 PID: 22345
I am a child2: 2 PID: 22346
I am a child2: 3 PID: 22347
I am a child2: 1 PID: 22349
I am a child2: 2 PID: 22350
I am a child2: 1 PID: 22344
I am a child2: 2 PID: 22352
I am a child2: 3 PID: 22353
I am a child2: 4 PID: 22354
I am a child2: 5 PID: 22355
I am a child2: 3 PID: 22351
I am a child2: 4 PID: 22356
I am a child2: 5 PID: 22357
I am a child2: 4 PID: 22348
I am a child2: 5 PID: 22358

Ответы [ 2 ]

2 голосов
/ 30 апреля 2010

Согласно комментарию, который вы сделали в ответе @ Cristina, проблема в том, что он разветвляет 20 child2 вместо только 5, как указано в аргументе командной строки. Причина в том, что каждый дочерний процесс, созданный forkChildren, возвращается к main и вызывает forkChildren2. Вы получаете 20 (фактически 25) child2, потому что 4 (forkChildren) * 5 (forkChildren2) = 20 плюс 5, созданных родительским процессом.

Я добавил возвращаемые значения в функции (в обе, чтобы они оставались одинаковыми) и условие if, чтобы пропустить forkChildren2, если это дочерний процесс.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int forkChildren(int nChildren) {
    int i;
    pid_t pid;
    for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
            /* error handling here, if needed */
            return -1;
        }
        if (pid == 0) {
            printf("I am a child: %d PID: %d\n",i, getpid());
            sleep(5);
            return 1;
        }
    }
    return 0;
}

int forkChildren2(int nChildren) {
    int i;
    pid_t pid;
    for (i = 1; i <= nChildren; i++) {
        pid = fork();
        if (pid == -1) {
            /* error handling here, if needed */
            return -1;
        }
        if (pid == 0) {
            printf("I am a child2: %d PID: %d\n", i, getpid());
            sleep(2);
            return 1;
        }
    }
    return 0;
}

int main(int argc, char **argv) {
    int ret;
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
        return EXIT_FAILURE;
    }
    ret = forkChildren(atoi(argv[1]));
    if (ret == 0)
        forkChildren2(atoi(argv[2]));
    // wait(...) for all pids here, if you wish
    return EXIT_SUCCESS;
}
2 голосов
/ 30 апреля 2010
[ozdeny@hyperion ~]$ I am a child2: 3 PID: 22336

Если это ваша проблема, это означает, что ваш корневой процесс завершается раньше, чем его дочерние процессы. Заставьте корень ждать своих дочерних процессов с помощью waitpid () [1].

[1] http://linux.die.net/man/2/waitpid

LE: Вы помещаете waitpid в корневой процесс, а не в разветвленный процесс.

LLE: Хорошо, я наконец-то получил то, что вы хотите сделать, и идея пришла из наблюдения jweyrich, это похоже на то, чтобы вернуть массив pids для своих дочерних процессов и затем завершить их из корневого процесса.

Главное должно выглядеть так:

int* child_pids
//mem allocation
forkChildren();
for each pid in child_pids
  kill(pid,*signal termination*)
forkChildren2()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...