2011-10-15 18 views
12

No entiendo por qué Unix tiene fork() para crear un nuevo proceso. En Win32 API tenemos CreateProcess() que crea un nuevo proceso y carga un ejecutable en su espacio de direcciones, luego comienza a ejecutarse desde el punto de entrada. Sin embargo, Unix ofrece fork para crear un nuevo proceso, y no entiendo por qué debería duplicar mi proceso si quisiera ejecutar otro proceso.¿Por qué Unix tiene fork() pero no CreateProcess()?

Así que me pregunto a estas dos preguntas:

  1. Si fork() y luego exec() es más eficiente, por qué no hay una función forkexec(const char *newProc) ya que vamos a llamar después de exec()fork() casi en todos los casos?
  2. Si no es más eficiente, ¿por qué existe fork()?
  3. sistemas operativos

Respuesta

11

La llamada fork() es suficiente. Es también es más flexible, le permite cosas como ajustar la redirección de E/S en el proceso secundario, en lugar de complicar la llamada al sistema para crear el proceso. Con los programas SUID o SGID, permite el niño pierde sus privilegios elevados antes de ejecutar el otro proceso.

Si desea una forma compleja de crear un proceso, busque la función posix_spawn().

#include <spawn.h> 

int posix_spawn(pid_t *restrict pid, const char *restrict path, 
     const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

int posix_spawnp(pid_t *restrict pid, const char *restrict file, 
      const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

La diferencia es la posix_spawnp() hace una búsqueda en el camino para el ejecutable.

Hay un conjunto completo de otras funciones para manejar los tipos posix_spawn_file_actions_t y posix_spawnattr_t (siga los enlaces 'Ver también' en la parte inferior de la página del manual al que se hace referencia).

Esto es bastante parecido a CreateProcess() en Windows. En su mayor parte, sin embargo, el uso de fork() seguido en breve por exec() es más simple.


No entiendo lo que quieres decir. El código de proceso secundario será escrito por mí, entonces, ¿cuál es la diferencia entre escribir if (fork() == 0) y poner este código al comienzo del main() del niño?

Muy a menudo, el código que ejecuta no está escrito por usted, por lo que no puede modificar lo que sucede al principio del proceso del niño. Piensa en un caparazón; si los únicos programas que ejecuta desde el shell son los que ha escrito, la vida será muy pobre.

Muy a menudo, el código que ejecuta se llamará desde muchos lugares diferentes. En particular, piense en un shell y un programa que a veces se ejecutará en una canalización y, a veces, se ejecutará sin canalizaciones. El programa llamado no puede decir qué redirecciones y correcciones de E/S debería hacer; el programa que llama sabe.

Si el programa de llamada se está ejecutando con privilegios elevados (privilegios SUID o SGID), es normal querer desactivarlos antes de ejecutar otro programa. Confiar en el otro programa para saber qué hacer es ... tonto.

+0

no entendí lo que quieres decir. código de proceso hijo será escrito por mí, entonces ¿cuál es la diferencia entre escribir if (fork() == 0) y poner este código al principio de main() del niño? –

+0

hmm, entonces usted dice que es más fácil con fork() - exec() que la pareja haga tales cosas (redirección de E/S, quitar privilegios, etc.) ¿lo entendí correctamente? –

+1

Sí: en comparación con las contorsiones requeridas para 'posix_spawn()', es mucho más simple usar 'fork()' y luego hacer que el niño realice las acciones que necesita, antes de usar 'exec()'. Lea la justificación para 'posix_spawn()'; es bastante esclarecedor (o, al menos, lo fue para mí). La lista de cosas que puede hacer con 'posix_spawn()' es impresionante, pero también es más compleja de lo que proporciona 'fork()'. –

3

tipo UNIX (por lo menos los nuevos núcleos Linux y BSD) por lo general tienen una muy eficientefork aplicación - es "tan barato" que no son "rosca" implementaciones basadas en ella, en algunos idiomas .

Al final la función forkexec es ~ n - para un valor pequeño de n líneas de código de aplicación.

seguro de que desea ventanas tenían como un útil ForkProcess :(

feliz de codificación.


Un cnicutar mencionó, Copy-On-Write (COW) es una estrategia usada.

+2

bien, pero si voy a transformar el proceso en otro después de tenedor muy eficiente, ¿no es mejor para crear la nueva proceso desde el principio? entonces no tengo que duplicar mi propio proceso. esto es lo que no consigo –

+0

@Ali Veli Las horquillas modernas no duplican el proceso en absoluto. Busque "copiar al escribir". – cnicutar

+0

digamos que crearé un nuevo proceso. c-o-w o no, el tenedor hace algo bien? entonces creo que si solo creara un nuevo proceso, no haría esto (incluso si solo es 1 instrucción). –

Cuestiones relacionadas