Как я могу разветвить максимум 5 дочерних процессов родителя одновременно? - PullRequest
0 голосов
/ 28 апреля 2010

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

struct {
   char *s1;
   char *s2;
} s[] = {
  {"one", "oneB"},
  {"two", "twoB"},
  {"three", "thr4eeB"},
  {"asdf", "3th43reeB"},
  {"asdfasdf", "thr33eeB"},
  {"asdfasdfasdf", "thdfdreeB"},
  {"af3c3", "thrasdfeeB"},
  {"fec33", "threfdeB"},
  {NULL, NULL}
};

int main(int argc, char *argv[])
{
int i, im5, children = 0;
int pid = fork();
for (i = 0; s[i].s2; i++)
{
    im5 = 0;
    switch (pid)
    {
        case -1:
        {
            printf("Error\n");
            exit(255);
        }
       case 0:
       {
            printf("%s -> %s\n", s[i].s1, s[i].s2);
            if (i==5) im5 = 1;
            printf("%d\n", im5);
            sleep(i);
            exit(1);
        }
        default:
        {   // Here is where I need to sleep the parent until chilren < 5 
            // so where do i decrement children so that it gets modified in the parent process?
            while(children > 5)
                sleep(1);
            children++;
            pid = fork();
        }
    }
}
return 1;
}

Исправленная версия, кажется, работает на основе комментариев

struct {
   char *s1;
   char *s2;
} s[] = {
  {"one", "oneB"},
  {"two", "twoB"},
  {"three", "thr4eeB"},
  {"asdf", "3th43reeB"},
  {"asdfasdf", "thr33eeB"},
  {"asdfasdfasdf", "thdfdreeB"},
  {"af3c3", "thrasdfeeB"},
  {"fec33", "threfdeB"},
  {NULL, NULL}
};

pthread_mutex_t children_count_lock;
int children = 0;

int main(int argc, char *argv[])
{
int i, im5;
int pid = fork();
for (i = 0; s[i].s2; i++)
{
    im5 = 0;
    switch (pid)
    {
        case -1:
        {
            printf("Error\n");
            exit(255);
        }
       case 0:
       {
            printf("%s -> %s\n", s[i].s1, s[i].s2);
            if (i==5) im5 = 1;
            printf("%d\n", im5);
            sleep(i);

            pthread_mutex_lock(&children_count_lock);
            children = children - 1;
            if (children < 0) children = 0;
            pthread_mutex_unlock(&children_count_lock);

            exit(1);
        }
        default:
        {   
            if (children > 4)
                wait();

            pthread_mutex_lock(&children_count_lock);
            children++;
            pthread_mutex_unlock(&children_count_lock);

            pid = fork();
        }
    }
}
return 1;
}

Ответы [ 3 ]

3 голосов
/ 28 апреля 2010

Семейство функций wait() приостанавливает родительский процесс до тех пор, пока дочерний процесс не завершится (сделайте это вместо сна).


Нет, вам не нужны критические разделы - ребенок и родитель не разделяют память. Все, что вам нужно, это что-то вроде этого в вашем случае по умолчанию:

    default:
    {   
        children++;  // Last fork() was successful

        while (children >= 5)
        {
            int status;
            // Wait for one child to exit
            if (wait(&status) == 0)
            {
                children--;
            }
        }

        pid = fork();
    }

(Забудьте, что я говорил ранее об инициализации children 1, я не заметил, что children++ должен был быть до цикла while).

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

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

1 голос
/ 28 апреля 2010

Звоните wait() в родительском.Это заблокирует, пока один из детей не выйдет.

...