Cada aplicación (programa) entra en ejecución a través de un proceso, el proceso es una instancia en ejecución de un programa. Los procesos se crean a través de diferentes llamadas al sistema, las más populares son fork() y exec()
pid_t pid = fork();
fork() crea un nuevo proceso duplicando el proceso de llamada. El nuevo proceso, denominado hijo, es un duplicado exacto del proceso de llamada, denominado padre, excepto por lo siguiente:
- El hijo tiene su propio ID de proceso único y este PID no coincide con el ID de ningún grupo de procesos existente.
- El Id. de proceso principal del hijo es el mismo que el Id. de proceso principal.
- El hijo no hereda los bloqueos de memoria y los ajustes de semáforo de su padre.
- El hijo no hereda operaciones de E/S asíncronas pendientes de su padre ni hereda ningún contexto de E/S asíncrona de su padre.
Valor de retorno de fork() En caso de éxito, el PID del proceso hijo se devuelve en el padre y 0 en el hijo. En caso de falla, se devuelve -1 en el padre, no se crea ningún proceso hijo y errno se establece de manera adecuada. Artículo detallado sobre la llamada al sistema de bifurcación
ejecutivo()
La familia de funciones exec() reemplaza la imagen del proceso actual con una nueva imagen del proceso. Carga el programa en el espacio de proceso actual y lo ejecuta desde el punto de entrada. La familia exec() consta de las siguientes funciones, he implementado execv() en el siguiente programa C, puede intentar descansar como ejercicio
int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char * const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[], char *const envp[]);
bifurcación vs ejecutivo
- fork inicia un nuevo proceso que es una copia del que lo llama, mientras que exec reemplaza la imagen del proceso actual con otra (diferente).
- Tanto el proceso principal como el secundario se ejecutan simultáneamente en caso de fork(), mientras que Control nunca regresa al programa original a menos que haya un error exec().
C
// C program to illustrate use of fork() & // exec() system call for process creation #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/wait.h> int main(){ pid_t pid; int ret = 1; int status; pid = fork(); if (pid == -1){ // pid == -1 means error occurred printf("can't fork, error occurred\n"); exit(EXIT_FAILURE); } else if (pid == 0){ // pid == 0 means child process created // getpid() returns process id of calling process // Here It will return process id of child process printf("child process, pid = %u\n",getpid()); // Here It will return Parent of child Process means Parent process it self printf("parent of child process, pid = %u\n",getppid()); // the argv list first argument should point to // filename associated with file being executed // the array pointer must be terminated by NULL // pointer char * argv_list[] = {"ls","-lart","/home",NULL}; // the execv() only return if error occurred. // The return value is -1 execv("ls",argv_list); exit(0); } else{ // a positive number is returned for the pid of // parent process // getppid() returns process id of parent of // calling process // Here It will return parent of parent process's ID printf("Parent Of parent process, pid = %u\n",getppid()); printf("parent process, pid = %u\n",getpid()); // the parent process calls waitpid() on the child // waitpid() system call suspends execution of // calling process until a child specified by pid // argument has changed state // see wait() man page for all the flags or options // used here if (waitpid(pid, &status, 0) > 0) { if (WIFEXITED(status) && !WEXITSTATUS(status)) printf("program execution successful\n"); else if (WIFEXITED(status) && WEXITSTATUS(status)) { if (WEXITSTATUS(status) == 127) { // execv failed printf("execv failed\n"); } else printf("program terminated normally," " but returned a non-zero status\n"); } else printf("program didn't terminate normally\n"); } else { // waitpid() failed printf("waitpid() failed\n"); } exit(0); } return 0; }
Producción:
parent process, pid = 11523 child process, pid = 14188 Program execution successful
Veamos las diferencias en forma tabular -:
tenedor() | ejecutivo() | |
1. | Es una llamada al sistema en lenguaje de programación C. | Es una llamada al sistema del sistema operativo. |
2. | Se utiliza para crear un nuevo proceso. | exec() ejecuta un archivo ejecutable |
3. | Su valor de retorno es un tipo entero | No crea nuevo proceso. |
4. | No toma ningún parámetro. | Aquí el identificador de proceso no cambia |
5. | Puede devolver tres tipos de valores enteros | En exec(), el código de máquina, los datos, el montón y la pila del proceso se reemplazan por el nuevo programa. |
Referencias: páginas man de Linux Este artículo es una contribución de Mandeep Singh . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA