syscall pid_t example c linux process operating-system

pid_t - Función de horquilla() en C



wait in c linux (3)

A continuación se muestra un ejemplo de la función Fork en acción. A continuación se muestra también la salida. Mi pregunta principal tiene que ver con la bifurcación que se llama cómo se cambian los valores. Así que pid1,2 y 3 comienzan en 0 y se cambian a medida que pasan los tenedores. ¿Esto se debe a que cada vez que ocurre una bifurcación, los valores se copian al hijo y el valor específico se cambia en el elemento primario? Básicamente, ¿cómo cambian los valores con las funciones de horquilla?

#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid1, pid2, pid3; pid1=0, pid2=0, pid3=0; pid1= fork(); /* A */ if(pid1==0){ pid2=fork(); /* B */ pid3=fork(); /* C */ } else { pid3=fork(); /* D */ if(pid3==0) { pid2=fork(); /* E */ } if((pid1 == 0)&&(pid2 == 0)) printf("Level 1/n"); if(pid1 !=0) printf("Level 2/n"); if(pid2 !=0) printf("Level 3/n"); if(pid3 !=0) printf("Level 4/n"); return 0; } }

Entonces esta es la ejecución.

----A----D--------- (pid1!=0, pid2==0(as initialized), pid3!=0, print "Level 2" and "Level 4") | | | +----E---- (pid1!=0, pid2!=0, pid3==0, print "Level 2" and "Level 3") | | | +---- (pid1!=0, pid2==0, pid3==0, print "Level 2") | +----B----C---- (pid1==0, pid2!=0, pid3!=0, print nothing) | | | +---- (pid1==0, pid2==0, pid3==0, print nothing) | +----C---- (pid1==0, pid2==0, pid3!=0, print nothing) | +---- (pid1==0, pid2==0, pid3==0, print nothing)

Idealmente, a continuación es cómo me gustaría verlo explicado, ya que de esta manera tiene sentido para mí. Los * son donde radica mi principal confusión. Cuando el niño se bifurca, por ejemplo, pid1 = fork(); eso crea un proceso con todos los valores del padre, pero ¿pasa un valor como digamos 1 a los padres pid1? ¿Significa que el hijo tendría pid 1 = 0, pid2 = 0 y pid3 = 0 y el padre entonces como pid1 = 2 y pid2 y 3 igual a 0?


La llamada al sistema fork () se usa para crear procesos. No toma argumentos y devuelve un ID de proceso. El propósito de fork () es crear un nuevo proceso, que se convierte en el proceso secundario de la persona que llama. Después de crear un nuevo proceso secundario, ambos procesos ejecutarán la siguiente instrucción luego de la llamada al sistema fork (). Por lo tanto, tenemos que distinguir al padre del niño. Esto se puede hacer probando el valor devuelto de fork ()

Fork es una llamada al sistema y no debes considerarlo como una función C normal. Cuando ocurre una bifurcación () , crea efectivamente dos procesos nuevos con su propio espacio de direcciones. Las variables que se inicializan antes de que la llamada a la bifurcación () almacenen los mismos valores en ambos espacios de direcciones. Sin embargo, los valores modificados en el espacio de direcciones de cualquiera de los procesos no se verán afectados en otro proceso, uno de los cuales es el principal y el otro es el secundario. Así que si,

pid=fork();

Si en los bloques de código subsiguientes verifica el valor de los procesos pid.Both se ejecutan para toda la longitud del código. Entonces, ¿cómo los distinguimos? Nuevamente, Fork es una llamada del sistema y aquí hay una diferencia. Dentro del proceso hijo recién creado, pid almacenará 0, mientras que en el proceso padre almacenará un valor positivo. Un valor negativo dentro de pid indica un error de fork.

Cuando probamos el valor de pid para determinar si es igual a cero o mayor que él, efectivamente estamos averiguando si estamos en el proceso hijo o en el proceso padre.

Leer más sobre Fork


Primero un enlace a alguna documentación de fork ()

http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html

El pid es proporcionado por el núcleo. Cada vez que el núcleo crea un nuevo proceso, aumentará el contador interno de pid y asignará al nuevo proceso este nuevo pid único y también se asegurará de que no haya duplicados. Una vez que el pid alcance un número alto, se ajustará y comenzará de nuevo.

Por lo tanto, nunca se sabe qué pid obtendrá de fork (), solo que el padre mantendrá su pid único y que se asegurará de que el proceso hijo tendrá un nuevo pid único. Esto se indica en la documentación proporcionada anteriormente.

Si continúas leyendo la documentación, verás que fork () devuelve 0 para el proceso secundario y el nuevo pid único del niño se devolverá al padre. Si el niño quiere saber que es su propio pid nuevo, tendrá que consultarlo usando getpid ().

pid_t pid = fork() if(pid == 0) { printf("this is a child: my new unique pid is %d/n", getpid()); } else { printf("this is the parent: my pid is %d and I have a child with pid %d /n", getpid(), pid); }

y abajo hay algunos comentarios en línea sobre tu código

#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid1, pid2, pid3; pid1=0, pid2=0, pid3=0; pid1= fork(); /* A */ if(pid1 == 0){ /* This is child A */ pid2=fork(); /* B */ pid3=fork(); /* C */ } else { /* This is parent A */ /* Child B and C will never reach this code */ pid3=fork(); /* D */ if(pid3==0) { /* This is child D fork''ed from parent A */ pid2=fork(); /* E */ } if((pid1 == 0)&&(pid2 == 0)) { /* pid1 will never be 0 here so this is dead code */ printf("Level 1/n"); } if(pid1 !=0) { /* This is always true for both parent and child E */ printf("Level 2/n"); } if(pid2 !=0) { /* This is parent E (same as parent A) */ printf("Level 3/n"); } if(pid3 !=0) { /* This is parent D (same as parent A) */ printf("Level 4/n"); } } return 0; }


int a = fork();

Crea un proceso duplicado "¿clonar?", Que comparte la pila de ejecución. La diferencia entre el padre y el hijo es el valor de retorno de la función.

El hijo que obtiene 0 devuelto, y el padre que recibe el nuevo pid.

Cada vez se copian las direcciones y los valores de las variables de pila. La ejecución continúa en el punto al que ya llegó en el código.

En cada fork , solo se modifica un valor: el valor de retorno de la fork .