2012-02-19 8 views
6

Учитывая приведенный ниже код:возвращаемое значение в vfork системы() вызова

int main() 
{ 
    int pid; 
    pid=vfork(); 
    if(pid==0) 
    printf("child\n"); 
    else 
    printf("parent\n"); 
    return 0; 
    } 

В случае vfork() адресса пространство, используемое родительского процесса и дочерний процесс такой же, поэтому одна копия переменной PID должен быть там. Теперь я не могу понять, как эта переменная pid может иметь два значения, возвращаемые vfork() i.e ноль для дочернего элемента и ноль для родителя?

В случае вилки() адресса пространство также копируется и есть две копий Pid переменных в каждом ребенке и родитель, так что я могу понять, в этом случае две разных копий могут иметь разные значения, возвращенную вилки(), но не может понять в случае vfork() Как pid имеет два значения, возвращаемые vfork()?

+2

Это смертоносное - вы можете 'exec()' или '_exit()' в ['vfork()'] (http://pubs.opengroup.org/onlinepubs/009695399/toc.htm) 'd child , но это именно так. Практически все остальное приводит к неопределенному поведению. Рекомендация: не используйте ['vfork()'] (http://pubs.opengroup.org/onlinepubs/007908799/xsh/vfork.html); действительно, я даже не потрудился бы научиться пользоваться им безопасно. Это похоже на 'gets()', функция, которую лучше притворяться, не существует. –

+1

@JonathanLeffler: 'vfork()' весьма полезен для систем без MMU. – ninjalj

+0

Да, сэр, я согласен с u, мы не должны его использовать, но я использовал vfork для решения одной проблемы создания дерева процессов и обмена данными между процессами разных уровней дерева, в этом случае vfork был полезен при использовании некоторой глобальной переменной. Я буду держать совет ур. –

ответ

6

Существует не 2 копии. Когда вы cal vfork родитель зависает, пока ребенок делает свою вещь (до тех пор, пока он не называет _exit(2) или execve(2)). Поэтому в любой момент есть только одна переменная pid.

В качестве побочного примечания, то, что вы делаете, является небезопасным. The standard записывает это ясно:

vfork() функция должна быть эквивалентна вилке(), за исключением того, поведения не определенно, если процесс, созданный vfork() либо изменяет какие-либо другие, чем переменные данные типа pid_t используется для хранения возвращаемого значения из vfork() или возвращается из функции, в которой был вызван vfork(), или вызывает любую другую функцию до успешного завершения , вызывая _exit() или одно из семейства exec функции.

В качестве второй стороне записки, vfork была удалена из SUSv4 - там действительно нет смысла использовать его.

+0

Это означает, что при запуске vfork созданный процесс может изменить значение типа переменной ** pid_t **, поэтому, когда дочерний элемент выйдет и родитель возобновит, как или кем будет восстановлено предыдущее значение ** pid_t ** переменной? ? –

+2

@ L.ppt Когда родительский континент 'pid_t' будет хранить PID дочернего элемента. – cnicutar

+2

@ L.ppt: компилятор специально рассматривает переменную 'pid_t', возвращаемую из' vfork() '. Он всегда находится в регистре и не проливается на память. – ninjalj