C Параллельные процессы

Я пытаюсь провести простой тест, чтобы увидеть, работают ли процессы одновременно.

Вот что у меня есть на данный момент:

pid_t pids[argc-1];
pid_t pid;

for(i=1; i<argc; i++)
{
    pid = fork();
    if (pid > 0)
    {
         pids[i-1] = pid;
         printf("process %d created\n", pid);
    }
    else
    {
         exit(0);
    }
}

printf("Main Process\n");

for (i=0; i < argc - 1; i++)
{
     int status;
     wait(pids[i], &status, 0);
     printf("Process %d finished\n", pids[i]);
}

В этом случае мой argc = 4, так что это создает 3 дочерних процесса, именно то, что мне нужно.

У меня вопрос: как я могу быть уверен, что все процессы работают одновременно? Я пробовал вызвать сон, но это не помогает, так как процессы создаются последовательно, и каждый сон заставляет их спать по одному. Я хотел установить второй дочерний процесс в спящий режим (1), чтобы посмотреть, будут ли другие два процесса печатать что-то, например, пока он спит, но я не могу сделать это внутри цикла for.

Кроме того, почему «Основной процесс» печатается только один раз? Разве каждый процесс, выполненный с помощью цикла for, не продолжает выполняться до тех пор, пока не будет возвращен оператор return? Я смущен этим.

Любая помощь приветствуется.

Спасибо.


person M. Averbach    schedule 10.02.2016    source источник
comment
Создайте еще один for цикл внутри первого for цикла для pid==0 case (дочерний случай), который просто спит и печатает свой собственный pid.   -  person kaylum    schedule 10.02.2016
comment
После разветвления порядок вывода полностью случайен.   -  person Koshinae    schedule 10.02.2016


Ответы (2)


Каждый дочерний процесс будет возвращать 0 в fork. Это означает, что они выполнят else часть вашего if блока, то есть exit. Другими словами, каждый клиентский процесс завершается почти сразу после запуска. Дети не печатают «Главный процесс», потому что они exit прежде, чем доберутся до него.

Если вы хотите, чтобы дочерние процессы переходили в спящий режим, вызовите функцию sleep в дочерней части кода, то есть в блоке else.

Например, вы можете сделать что-то вроде этого:

...
else
{
     printf("in child %d\n", getpid());
     sleep(1);
     printf("in child %d\n", getpid());
     sleep(3);
     exit(0);
}

РЕДАКТИРОВАТЬ:

Я объясню более подробно, что именно происходит:

На первой итерации цикла for исходный процесс вызывает fork. Эта функция возвращает дважды: один раз родительскому объекту, где он возвращает pid дочернего элемента, и один раз дочернему элементу, где он возвращает 0.

Родитель переходит в блок if, где обновляет свой список идентификаторов и возвращается к началу цикла. Потомок переходит в часть else, где вызывает exit, который завершает дочерний процесс.

Исходный родительский процесс теперь снова является вершиной цикла for, и вышеуказанный процесс повторяется еще 3 раза.

person dbush    schedule 10.02.2016
comment
но в этом случае я все еще создаю 3 дочерних процесса. А как насчет тех процессов, где pid ›0? Почему эти процессы не попадают в основной процесс? - person M. Averbach; 10.02.2016
comment
@ M.Averbach Есть только один процесс, где pid ›0: исходный. Он выполняет цикл, а затем печатает основной процесс. - person Gilles 'SO- stop being evil'; 10.02.2016

Как сказал М. Авербах, ваш опубликованный код выйдет так быстро, что их будет трудно обнаружить. Но чтобы ответить на ваш вопрос о том, как проверить, запущены ли процессы:

Однако, если процессы просуществовали немного дольше, их можно было бы обнаружить с помощью базовой команды «ps», которая гарантирует, что процессы запущены:

   ps

Если у ваших дочерних процессов могут быть свои собственные дочерние процессы, может быть полезно использование формы, которая отображается в древовидном формате:

   ps jf
person Gilbert    schedule 10.02.2016