NOMBRE¶
clone - crea un proceso hijo
SINOPSIS¶
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg);
_syscall2(int, clone, int, flags, void *,
child_stack)
DESCRIPCIÓN¶
clone crea un nuevo proceso como lo hace
fork(2).
clone es
una función de biblioteca situada encima de la llamada al sistema
subyacente
clone , de aquí en adelante referida como
sys_clone. Una descripción de
sys_clone se da hacia el
final de esta página.
A diferencia de
fork(2), estas llamadas permiten al proceso hijo
compartir partes de su contexto de ejecución con el proceso invocador,
tales como el espacio de memoria, la tabla de descriptores de fichero y la
tabla de manejadores de señal. (Observe que en esta página de
manual, "proceso invocador" normalmente se corresponde con
"proceso padre". Vea la descripción de
CLONE_PARENT
más abajo.)
El principal uso de
clone es para implementar los hilos: múltiples
hilos de control en un programa que se ejecutan concurrentemente en un espacio
de memoria compartido.
Cuando se crea el proceso hijo con
clone, éste ejecuta la
función
fn(
arg). (Eso difiere de
fork(2), en donde
la ejecución continúa en el hijo desde el punto en el que se
encuentra la llamada
fork(2) El argumento
fn es un puntero a una
función que es ejecutada por el proceso hijo al comienzo de su
ejecución. El argumento
arg se pasa a la función
fn.
Cuando la función
fn(
arg) regresa, el proceso hijo termina.
El entero devuelto por
fn es el código de salida del proceso hijo.
El proceso hijo también puede terminar explícitamente ejecutando
exit(2) o después de recibir una señal fatal.
El argumento
child_stack indica la posición de la pila utilizada por
el proceso hijo. Puesto que los procesos hijo e invocador pueden compartir la
memoria, no es posible, en general, para el proceso hijo ejecutarse usando la
misma pila que el proceso invocador. Por tanto, el proceso invocador debe
preparar un área de memoria para la pila del hijo y pasar un puntero a
dicha área a
clone. Las pilas crecen hacia abajo en todos los
procesadores en los que se ejecuta Linux (excepto en el procesador HP PA), por
lo que
child_stack apunta normalmente a la dirección más alta
de la zona de memoria preparada para la pila del hijo.
El byte bajo de
flags contiene el número de la señal enviada al
padre cuando el hijo muere. Si la señal especificada es cualquiera
distinta de
SIGCHLD, el proceso padre debe especificar las opciones
__WALL o
__WCLONE cuando espera al hijo con
wait(2). Si
no se indica ninguna señal, el proceso padre no es notificado cuando el
hijo termina.
flags puede también ser operado con un OR a nivel de bits (bitwise
or) con una o varias de las siguientes constantes, para así especificar
qué van a compartir los procesos invocador e hijo:
- CLONE_PARENT
- (Linux 2.4 en adelante) Si CLONE_PARENT está
presente, el padre del nuevo hijo (valor devuelto por getppid(2))
será el mismo que el del proceso invocador.
Si CLONE_PARENT no está presente, (al igual que ocurre con
fork(2)) el padre del hijo es el proceso invocador.
Observe que es el proceso padre, tal como informa getppid(2), el que
es notificado cuando el hijo termina, así que si se especifica la
opción CLONE_PARENT , será notificado el padre del
proceso invocador, en lugar del propio proceso invocador.
- CLONE_FS
- Si se pone CLONE_FS, los procesos invocador e hijo
comparten la misma información del sistema de ficheros. Ésta
incluye la raíz del sistema de ficheros, el directorio de trabajo
actual y el valor de umask. Cualquier llamada a chroot(2),
chdir(2) o umask(2) realizada por el proceso invocador o
hijo también afecta al otro proceso.
Si no se pone CLONE_FS, el proceso hijo trabaja con una copia de la
información del sistema de ficheros del proceso invocador en el
momento de ejecutar la llamada clone. Las llamadas a
chroot(2), chdir(2) o umask(2) realizadas
después por uno de los procesos no afectan al otro.
- CLONE_FILES
- Si se pone CLONE_FILES, los procesos invocador e
hijo comparten la misma tabla de descriptores de fichero. Los descriptores
de fichero siempre se refieren a los mismos ficheros en el invocador y en
el proceso hijo. Cualquier descriptor de fichero creado por el proceso
invocador o por el proceso hijo también es válido en el otro
proceso. De igual forma, si uno de los procesos cierra un descriptor de
fichero o cambia sus banderas (flags) asociadas, el otro proceso
también se verá afectado.
Si no se pone CLONE_FILES, el proceso hijo hereda una copia de todos
los descriptores de fichero abiertos en el proceso invocador en el momento
de ejecutar clone. Las operaciones sobre los descriptores de
fichero realizadas después por uno de los procesos invocador o hijo
no afectan al otro.
- CLONE_NEWNS
- (Linux 2.4.19 en adelante) Comienza el hijo en un nuevo
espacio de nombres.
Cada proceso vive en un espacio de nombres. El espacio de nombres de
un proceso viene dado por los datos (el conjunto de montajes) que
describen la jerarquía de ficheros tal como la ve ese proceso.
Después de una llamada a fork(2) o clone(2) con la
bandera CLONE_NEWNS desactivada, el hijo vive en el mismo espacio
de nombres que el padre. Las llamadas al sistema mount(2) y
umount(2) cambian el espacio de nombres del proceso invocador, y
por tanto afectan a todos los procesos que viven en el mismo espacio de
nombres, pero no a los que están en un espacio de nombres diferente.
Tras una llamada a clone(2) con la bandera CLONE_NEWNS
activada, el hijo clonado comienza su ejecución en un nuevo espacio
de nombres, inicializado con una copia del espacio de nombres del padre.
Solamente un proceso privilegiado puede indicar la bandera
CLONE_NEWNS. No está permitido especificar CLONE_NEWNS
y CLONE_FS en la misma llamada a clone.
- CLONE_SIGHAND
- Si se pone CLONE_SIGHAND, los procesos invocador e
hijo comparten la misma tabla de manejadores de señal. Si el proceso
invocador o hijo llama a sigaction(2) para cambiar el
comportamiento asociado a una señal, el comportamiento también
se cambia en el otro proceso. Sin embargo, los procesos invocador e hijo
todavía tienen diferentes máscaras de señales y conjuntos
de señales pendientes. Por tanto, uno de ellos puede bloquear o
desbloquear algunas señales usando sigprocmask(2) sin afectar
al otro proceso.
Si no se pone CLONE_SIGHAND, el proceso hijo hereda una copia de los
manejadores de señal del proceso invocador en el momento de ejecutar
clone. Las llamadas a sigaction(2) realizadas después
por uno de los procesos no tendrán efecto sobre el otro proceso.
- CLONE_PTRACE
- Si se especifica la opción CLONE_PTRACE , y el
proceso invocador está siendo rastreado, también se rastrea al
hijo (vea ptrace(2)).
- CLONE_VFORK
- Si la opción CLONE_VFORK está presente, la
ejecución del proceso invocador se suspende hasta que el hijo libere
sus recursos de memoria virtual mediante una llamada a execve(2) o
_exit(2) (al igual que con vfork(2)).
Si CLONE_VFORK no está presente tanto el proceso invocador como
el hijo son planificables tras la llamada, y una aplicación no
debería confiar en que se ejecuten en un determinado orden.
- CLONE_VM
- Si CLONE_VM está presente, el proceso invocador
y el proceso hijo se ejecutan en el mismo espacio de memoria. En
particular, las escrituras en memoria realizadas por el proceso invocador
o el hijo son visibles también en el otro proceso. Además,
cualquier ubicación o eliminación de memoria realizada con
mmap(2) o munmap(2) por el proceso hijo o invocador
también afecta al otro proceso.
Si CLONE_VM no está presente, el proceso hijo se ejecuta en una
copia separada del espacio de memoria del proceso invocador en el momento
de la llamada a clone. Las escrituras en memoria o las
ubicaciones/eliminaciones de ficheros realizadas por uno de los procesos
no afecta al otro, al igual que con fork(2).
- CLONE_PID
- Si se pone CLONE_PID, se crea el proceso hijo con el
mismo identificador de proceso que el proceso invocador.
Si no se pone CLONE_PID, el proceso hijo posee un identificador de
proceso único, distinto del identificador del invocador.
Esta bandera sólo puede ser especificada por el proceso de arranque del
sistema (PID 0).
- CLONE_THREAD
- (Linux 2.4 en adelante) Si CLONE_THREAD está
presente, el proceso hijo se pone en el mismo grupo de hilos que el
proceso invocador.
Si CLONE_THREAD no está presente, el proceso hijo se pone en su
propio (nuevo) grupo de hilos, cuyo identificador es el mismo que el
identificador de proceso.
(Los grupos de hilos son una característica añadida en Linux 2.4
para soportar la noción de un conjunto de hilos compartiendo un solo
PID impuesta por los hilos POSIX. En Linux 2.4, las llamadas a
getpid(2) devuelven el identificador de grupo de hilos del
invocador.)
La llamada al sistema
sys_clone se corresponde más estrechamente con
fork(2) en el hecho de que la ejecución en el proceso hijo
continúa desde el punto de la llamada. Así,
sys_clone
solamente requiere los argumentos
flags y
child_stack , que
tienen el mismo significado que para
clone. (Observe que el orden de
estos argumentos difiere de
clone.)
Otra diferencia de
sys_clone es que el argumento
child_stack puede
ser cero, en cuyo caso la semántica de copia-en-escritura (copy-on-write)
asegura que el proceso hijo obtendrá copias de las páginas de pila
cuando cualquiera de los dos procesos modifique la pila. En este caso, para
una operación correcta, debería especificarse la opción
CLONE_VM.
VALOR DEVUELTO¶
En caso de éxito, se devuelve el PID del hijo en el hilo de ejecución
del invocador. En caso de fallo, se devuelve -1 en el contexto del invocador,
no se creará ningún proceso hijo y se asignará a la variable
errno un valor apropiado.
ERRORES¶
- EAGAIN
- Se están ejecutando ya demasiados procesos.
- ENOMEM
- __clone no puede reservar suficiente memoria para
obtener una estructura de tarea (task structure) para el hijo o para
copiar aquellas partes del contexto del padre que necesitan ser
copiadas.
- EINVAL
- Devuelto por clone cuando se especifica un valor
cero para child_stack.
- EINVAL
- Se especificaron ambas opciones CLONE_FS y
CLONE_NEWNS en flags.
- EINVAL
- Se especificó CLONE_THREAD , pero no
CLONE_SIGHAND. (Desde Linux 2.5.35.)
- EPERM
- Se especificó CLONE_PID por un proceso cuyo PID
es distinto de cero.
FALLOS¶
Desde la versión 2.1.97 del núcleo, no se debe usar la bandera
CLONE_PID ya que otras partes del núcleo y la mayoría del
software del sistema todavía asumen que los identificadores de proceso
son únicos.
No hay una entrada para
clone en la versión 5 de libc. libc 6 (o
sea, glibc 2) proporciona una llamada
clone tal como la que se ha
descrito en esta página de manual.
OBSERVACIONES¶
Para las versiones del núcleo 2.4.7-2.4.18 la bandera CLONE_THREAD implica
la bandera CLONE_PARENT.
Las llamadas
clone y
sys_clone son específicas de Linux y no
deberían usarse en aquellos programas que pretendan se portables. Para
programar aplicaciones con hilos (múltiples hilos de control en el mismo
espacio de memoria) es mejor usar una biblioteca que implemente la API de
hilos POSIX 1003.1c, como la biblioteca LinuxThreads (incluida en glibc2). Vea
pthread_create(3).
Esta página de manual se corresponde con los núcleos 2.0.x, 2.1.x,
2.2.x, 2.4.x, y con las versiones 2.0.x y 2.1.x de glibc.
VÉASE TAMBIÉN¶
fork(2),
wait(2),
pthread_create(3)