2016-11-06 4 views

ответ

5

Process IDs: ляющих и родительского процессов

все работающие программы имеют уникальный идентификатор процесса. process ID, a неотрицательное целое число, является единственным идентификатором процесса, который является всегда уникальным. Но идентификаторы процессов повторно используются.

По мере завершения процесса его идентификатор становится доступным для повторного использования. Определенные системы повторно используют повторное использование, так что вновь созданные процессы не путаются со старыми.

Некоторые идентификаторы являются «зарезервированными» в том смысле, что они используются системными процессами , такими как планировщик . Другим примером является init процесс, который всегда занимает PID 1. В зависимости от системы идентификатор может быть активно зарезервирован.

Запуск команды

> ps -eaf | head -n 5 
UID  PID PPID C STIME TTY   TIME CMD 
root   1  0 0 11:49 ?  00:00:02 /sbin/init splash 
root   2  0 0 11:49 ?  00:00:00 [kthreadd] 
root   3  2 0 11:49 ?  00:00:00 [ksoftirqd/0] 
root   5  2 0 11:49 ?  00:00:00 [kworker/0:0H] 

и

> pidof init 
1 

позволит вам самостоятельно убедиться в этом.

В C мы можем использовать следующие функции для получения идентификатора процесса вызывающего процесса и идентификатор процесса вызывающего процесса,

#include <unistd.h> 

pid_t getpid(void); 
pid_t getppid(void); 

Процесс может создавать другие процессы. Созданные процессы называются «дочерние процессы», и мы ссылаемся на процесс, который их создал как «родительский процесс » ».

Создание нового процесса с помощью вилки()

Для создания дочернего процесса мы используем системный вызов fork()

#include <unistd.h> 

pid_t fork(void); 

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

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

Процесс может иметь только один родительский процесс, который всегда можно получить по телефону getppid.

Ребенок является копия родителя, он получает скопировать из родительского данных пространства, кучи и стека. Они делают не делят эти части памяти!

Мы скомпилировать и выполнить следующий фрагмент кода, чтобы увидеть, как это работает,

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/syscall.h> 

int main(void) { 
    int var = 42; // This variable is created on the stack 
    pid_t pid; 

    // Two processes are created here 
    //     v~~~~~~~~~~| 
    if ((pid = fork()) < 0) { 
     perror("Fork failed"); 
    } else if (pid == 0) { // <- Both processes continue executing here 
     // This variable gets copied 
     var++; 

     printf("This is the child process:\n" 
       "\t my pid=%d\n" 
       "\t parent pid=%d\n" 
       "\t var=%d\n", getpid(), getppid(), var); 

    } else { 
     printf("This is the parent process:\n" 
       "\t my pid=%d\n" 
       "\t child pid=%d\n" 
       "\t var=%d\n", getpid(), pid, var); 

    } 


    return 0; 
} 

Мы увидим, когда мы выполняем программу, что нет никаких гарантий , какой процесс получает выполнить сначала. Они могут даже работать одновременно, эффективно перемежая их выход.

$ # Standard compilation 
$ gcc -std=c99 -Wall fork_example1.c -o fork_example1 
$ # Sometimes the child executes in its entirety first 
$ ./fork_example1 
This is the child process: 
    my pid=26485 
    parent pid=26484 
    var=43 
This is the parent process: 
    my pid=26484 
    child pid=26485 
    var=42 
$ # and sometimes the parent executes in its entirety first 
$ ./fork_example1 
This is the parent process: 
    my pid=26461 
    child pid=26462 
    var=42 
This is the child process: 
    my pid=26462 
    parent pid=26461 
    var=43 
$ # At times the two might interleave 
$ ./fork_example1 
This is the parent process: 
    my pid=26455 
This is the child process: 
    my pid=26456 
    parent pid=26455 
    var=43 
    child pid=26456 
    var=42 

ПИД обозначает идентификатор процесса и PPID обозначает идентификатор родительского процесса.

Процесс ID 0 зарезервирован для использования ядром, поэтому не возможно 0 быть идентификатор процесса ребенка.

Многие системы не выполняют полную копию этих сегментов памяти, а вместо этого только создает копию, когда либо процесс выполняет запись. Первоначально общие области отмечены ядром как «только для чтения», и всякий раз, когда процесс пытается изменить эти области , ядро ​​присуждает каждому процессу свою собственную копию этой памяти.

Стандарт буферизирован, поэтому это не прекрасный пример.

+0

Легко узнать, какой процесс является дочерним, когда это ваши процессы, но я думаю, что вопрос заключается в определении этого вопроса о pids других процессов. – interjay

+2

И я верю, что ваш второй пример на самом деле говорит вам, что вы находитесь в основном потоке процесса, а не в основном процессе (что бы это ни значило). – interjay

1

Используйте функции getpid() и getppid(), чтобы получить идентификатор процесса и идентификатор родительского процесса.

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