2014-09-20 3 views
-2

У меня есть программа, которая должна запустить другой процесс и работать одновременно с ним. Я использую fork() и system(), чтобы выполнить это. У меня есть код, подтверждающий, что мой вызов system() возвращает, но каждый раз, когда я выполняю это, я должен вручную завершить выполнение, набрав ctrl c. Я могу сказать, что один из моих процессов завершается, но я не совсем уверен, какой из них. Я считаю, что это родитель. Оба должны быть пойманы возвратными заявлениями.Почему мне приходится прерывать свою программу вручную?

Вот родительский процесс код (forkWaitTest):

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

using namespace std; 

int main(void) 
{ 
     pid_t childPID; 
     int status; 

     childPID = fork(); 
     if(childPID >=0) 
     { 
       if(childPID == 0) 
       { 
         cout <<"I'm the fork child"; 
         cout.flush(); 
         status=system("child"); 
         cout << "status = " << status; 
         //exit(0); 
         //cout << "Am I getting here?"; 
       } 
       else{ 
       cout << "I am the parent and can keep doing things "; 
       int y=1; 
       int x=7; 
       cout<< y+x << " "; 
       } 
     } 
     return 0; 
} 

Это дочерний процесс, который называется

#include <stdio.h> 

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

    printf("I am the child\n"); 
    return 0; 
} 

Вот мой результат:

-bash-4.2$ forkWaitTest 
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child 
status = 0 
+0

Как вы определили, что что-то «никогда не заканчивается»? –

+0

Я должен нажать 'ctrl c', чтобы закончить его – art3m1sm00n

+0

Ваш родитель должен быть' wait() 'ing для дочернего элемента, хотя, по общему признанию, я не могу сразу понять, почему это не приведет к поведению. – abligh

ответ

3

Ваш родитель DID прекратить. Давайте посмотрим на ваш вывод:

-bash-4.2$ forkWaitTest 
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child 
status = 0 

Теперь давайте рассмотрим, что более близко, особенно этот бит:

I'm the fork child-bash-4.2$ 

Престол, прямо в середине, это говорит bash-4.2$. Это командная строка после завершения родительского контроля.Затем ребенок запускается и также выходит, но вы сбиты с толку, когда он печатает после подсказки bash. Ваш ^C просто печатает следующую строку.

Для проверки нажмите на ссылку несколько раз, а не ^C.

+0

О, ничего себе. Так что на самом деле это заканчивается, похоже, не похоже? Вау, я чувствую себя глупым. БЛАГОДАРЯ! Это первый раз, когда я когда-либо занимался несколькими процессами, запущенными сразу – art3m1sm00n

+0

Мы все были там ... – abligh

1

Убедитесь ваши сообщения заканчиваются символами новой строки (например, добавьте << endl к выходам).

Я вижу ваш bash запрос (-bash-4.2$), смешанный с другими выходами, отчасти потому, что у вас нет новых строк на выходах, а отчасти потому, что ваш код не показывает попыток подождать, пока дети умрут. Это означает, что ваш процесс действительно умер.

Вы можете ввести: ls -l, и оболочка выполнит эту команду, потому что она ждет вас, чтобы ввести что-то. Когда вы прерываете его (оболочку), он снова запрашивает, но он принял бы ваш вход даже без прерывания.


С слегка модифицированной версией child:

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

int main(void) 
{ 
    printf("I am the walrus (%d)\n", (int)getpid()); 
    return 0; 
} 

и слегка модифицированной версии материнской:

#include <cstdlib> 
#include <iostream> 
#include <sys/wait.h> 
#include <unistd.h> 

using namespace std; 

int main(void) 
{ 
    pid_t childPID; 
    int status; 

    childPID = fork(); 
    if (childPID >= 0) 
    { 
     if (childPID == 0) 
     { 
      cout << "I'm the forked child (" << getpid() << ")\n"; 
      cout.flush(); 
      status = system("child"); 
      cout << "status = " << status << endl; 
      cout << "Am I getting here?\n"; 
      return 0; 
     } 
     else 
     { 
      cout << "I am the parent and can keep doing things "; 
      int y = 1; 
      int x = 7; 
      cout << y + x << endl; 
     } 
    } 
    int corpse; 
    while ((corpse = wait(&status)) != -1) 
     cout << "PID " << corpse << " exited with status " << status << endl; 
    return 0; 
} 

и с быстрой Osiris JL:, пример выхода Я получаю:

Osiris JL: ./parent 
I am the parent and can keep doing things 8 
I'm the forked child (3192) 
I am the walrus (3193) 
status = 0 
Am I getting here? 
PID 3192 exited with status 0 
Osiris JL: 

Обратите внимание, что «дочерняя» программа выполняется дочерним элементом собственного дочернего процесса родительского процесса (поэтому печатаются значения getpid()). И wait() в цикле в родительском процессе гарантирует, что ребенок умер до того, как родитель умрет. Учитывая структуру дочернего процесса, в котором используется функция system(), процесс внука (выполняющий частично пропущенный процесс child) завершился до того, как ребенок выйдет до выхода родителя. Пропустите петлю wait() и родитель может легко выйти до того, как ребенок и внук сделать:

Osiris JL: ./parent 
I am the parent and can keep doing things 8 
I'm the forked child (3207) 
Osiris JL: I am the walrus (3208) 
status = 0 
Am I getting here? 
ls -ld parent* child* 
-rwxr-xr-x 1 jleffler staff 8784 Sep 20 15:57 child 
-rw-r--r-- 1 jleffler staff 122 Sep 20 15:57 child.cpp 
drwxr-xr-x 3 jleffler staff 102 Sep 20 15:57 child.dSYM 
-rwxr-xr-x 1 jleffler staff 9808 Sep 20 16:02 parent 
-rw-r--r-- 1 jleffler staff 858 Sep 20 16:02 parent.cpp 
drwxr-xr-x 3 jleffler staff 102 Sep 20 16:02 parent.dSYM 
Osiris JL: 
+0

Хорошо, я сделал это, но все, что он сделал, это переформатировать мой вывод. Это ничего не помогло. – art3m1sm00n