2012-10-18 3 views
2

Я изучаю компьютерные системы, и я сделал эту очень простую функцию, которая использует fork() для создания дочернего процесса. fork() возвращает pid_t, то есть 0, если это дочерний процесс. Но вызов функции getpid() в этом дочернем процессе возвращает другой ненулевой pid. В приведенном ниже коде есть newPid только значимый в контексте программы, а не в операционной системе? Возможно ли это только относительное значение, измеренное против pid родителя?Может ли процесс иметь два PID?

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

void unixError(char* msg) 
{ 
    printf("%s: %s\n", msg, strerror(errno)); 
    exit(0); 
} 

pid_t Fork() 
{ 
    pid_t pid; 
    if ((pid = fork()) < 0) 
     unixError("Fork error"); 
    return pid; 
} 


int main(int argc, const char * argv[]) 
{ 
    pid_t thisPid, parentPid, newPid; 
    int count = 0; 
    thisPid = getpid(); 
    parentPid = getppid(); 

    printf("thisPid = %d, parent pid = %d\n", thisPid, parentPid); 

    if ((newPid = Fork()) == 0) { 
     count++; 
     printf("I am the child. My pid is %d, my other pid is %d\n", getpid(), newPid); 
     exit(0); 
    } 
    printf("I am the parent. My pid is %d\n", thisPid); 
    return 0; 
} 

Выход:

thisPid = 30050, parent pid = 30049 
I am the parent. My pid is 30050 
I am the child. My pid is 30052, my other pid is 0 

Наконец, почему PID ребенка 2 выше, чем у родителя, а не 1? Разница между pid главной функции и ее родителем равна 1, но когда мы создаем дочерний элемент, он увеличивает pid на 2. Почему?

ответ

6

От вилки man страницы:

Возвращаемое значение

В случае успеха, PID дочернего процесса возвращается в родителе, и 0 возвращается в дочернем. При ошибке -1 возвращается в родительском , никакого дочернего процесса не создается, а errno устанавливается соответствующим образом.

Вилка не возвращает pid ребенка, только в родительском. Поэтому у дочернего процесса нет двух pids.

Попробуйте

int main(int argc, const char * argv[]) 
{ 
    pid_t thisPid, parentPid, newPid; 
    int count = 0; 
    thisPid = getpid(); 
    parentPid = getppid(); 

    printf("thisPid = %d, parent pid = %d\n", thisPid, parentPid); 

    if ((newPid = Fork()) == 0) { 
     count++; 
     printf("I am teh child. My pid is %d\n", getpid()); 
     exit(0); 
    } 
    else 
     printf("I am the parent. My pid is %d, my child pid is %d\n", thisPid, newPid); 
    return 0; 
} 
+0

Разъясняется отлично. Спасибо, что поняли это. –

+0

Я полагаю, вы хотели напечатать результат от 'getpid' у ребенка? Теперь он печатает 0. –

+0

Действительно, спасибо, что указали это. – tomahh

0

Нет, pid назначается ровно одному процессу за раз.

Идентификаторы процесса не должны следовать никаким правилам при назначении процессам. Итак, если это выглядит так, как будто pid ребенка является приращением pid родителя, это просто удача.

С помощью pid определенных процессов невозможно сделать какие-либо выводы относительно отношений процессов.

+0

Thanks; вы можете уточнить? –

1

PIDS один за процессом. Для процесса никогда не будет более 1 pid - внутренние структуры данных, которые обрабатывают процесс в ОС, имеют только одно поле PID.

Кроме того, когда вы звоните вилку() клонирование процесса, называемые вилы, производя точно дублировать его - все файловые дескрипторы, всю память, и т.д .. КРОМЕ для его PID. Вот почему fork возвращает разные значения в зависимости от того, является ли вы дочерним или родительским процессом. Эти разные значения возвращаемого значения позволяют программе знать, является ли это дочерним или родительским. Ребенок получает 0, и поэтому может знать, что это ребенок.

0

PID не являются последовательными при назначении (фактически не соблюдайте никаких правил), и один процесс имеет только один PID за раз. Также не может быть двух процессов, которые используют один и тот же PID.

Смежные вопросы