Linus Torvalds (torvalds@cs.helsinki.fi)
Martes, 6 de agosto de 1996 12:47:31 +0300 (EET DST)
Mensajes ordenados por: [fecha] [hilo] [asunto] [autor]
Mensaje siguiente: Bernd P. Ziller: "Re: Vaya en get_hash_table"
Mensaje anterior: Linus Torvalds: "Re: pedido de E / S"
El lunes 5 de agosto de 1996, Peter P. Eiserloh escribió:
Necesitamos mantener claro el concepto de hilos. Demasiada gente parece confundir un hilo con un proceso. La siguiente discusión no refleja el estado actual de Linux, sino que es un intento de mantenerse en una discusión de alto nivel.
¡NO!
NO hay razón para pensar que los "hilos" y los "procesos" son entidades separadas. Así es como se hace tradicionalmente, pero personalmente creo que es un gran error pensar de esa manera. La única razón para pensar de esa manera es el equipaje histórico.
Tanto los subprocesos como los procesos son realmente una sola cosa: un "contexto de ejecución". Intentar distinguir artificialmente diferentes casos es solo autolimitado.
Un "contexto de ejecución", por el presente denominado COE, es solo el conglomerado de todo el estado de ese COE. Ese estado incluye cosas como el estado de la CPU (registros, etc.), el estado de MMU (asignaciones de página), el estado de permiso (uid, gid) y varios "estados de comunicación" (archivos abiertos, controladores de señales, etc.). Tradicionalmente, la diferencia entre un "subproceso" y un "proceso" ha sido principalmente que los subprocesos tienen estado de CPU (+ posiblemente algún otro estado mínimo), mientras que el resto del contexto proviene del proceso. Sin embargo, esa es solo
una forma de dividir el estado total del COE, y no hay nada que diga que es la forma correcta de hacerlo. Limitarse a ese tipo de imagen es simplemente estúpido.
La forma en Linux piensa acerca de esto (y la forma en que quiere que las cosas de trabajo) es que no es ninguna cosa tal como un "proceso" o un "hilo". Solo existe la totalidad del COE (llamado "tarea" por Linux). Diferentes COE pueden compartir partes de su contexto entre sí, y un subconjunto de ese intercambio es la configuración tradicional de "hilo" / "proceso", pero eso realmente debería verse como SOLO un subconjunto (es un subconjunto importante, pero esa importancia viene no desde el diseño, sino desde los estándares: obviamente, también queremos ejecutar programas de hilos que cumplan con los estándares sobre Linux).
En resumen: NO diseñe alrededor de la forma de pensar del hilo / proceso. El núcleo debe diseñarse en torno a la forma de pensar del COE, y luego la biblioteca pthreads puede exportar la interfaz limitada de pthreads a los usuarios que desean utilizar esa forma de ver los COE.
Solo como un ejemplo de lo que se hace posible cuando piensas COE en lugar de hilo / proceso:
- Puede hacer un programa "cd" externo, algo que tradicionalmente es imposible en UNIX y / o proceso / thread (ejemplo tonto, pero la idea es que puede tener este tipo de "módulos" que no están limitados al UNIX tradicional / configuración de hilos). Hacer un:
clonar (CLONE_VM | CLONE_FS);
hijo: execve ("external-cd");
/ * el "execve ()" desasociará la VM, por lo que la única razón por la que usamos CLONE_VM fue hacer que el acto de clonar sea más rápido * /
- Puede hacer "vfork ()" de forma natural (se necesita un soporte mínimo del núcleo, pero ese soporte se adapta perfectamente a la forma de pensar CUA):
clonar (CLONE_VM);
child: continuar corriendo, eventualmente execve ()
madre: espera al execve
- puedes hacer "demonios IO" externos:
clon (CLONE_FILES);
hijo: descriptores de archivos abiertos, etc.
madre: usa los fd's que abrió el niño y vv.
Todo lo anterior funciona porque no estás atado a la forma de pensar del hilo / proceso. Piense en un servidor web, por ejemplo, donde los scripts CGI se realizan como "hilos de ejecución". No puede hacer eso con hilos tradicionales, porque los hilos tradicionales siempre tienen que compartir todo el espacio de direcciones, por lo que tendría que vincular todo lo que siempre quiso hacer en el servidor web (un "hilo" no puede ejecutarse otro ejecutable).
Pensando en esto como un "contexto de la ejecución del" problema en su lugar, sus tareas ahora puede elegir para ejecutar programas externos (= separar el espacio de direcciones del padre), etc, si quieren, o pueden, por ejemplo, compartir todo con los padres , excepto para los descriptores de archivo (para que los sub "subprocesos" puedan abrir muchos archivos sin que el padre necesite preocuparse por ellos: se cierran automáticamente cuando el sub "subproceso" sale, y no usa fd's en el padre) .
Piense en un "inetd" roscado, por ejemplo. Desea un bajo fork + exec, por lo que con la forma de Linux que puede en lugar de usar un "fork ()", escribe un inetd multiproceso donde cada subproceso se crea con solo CLONE_VM (comparta el espacio de direcciones, pero no comparta el archivo descriptores, etc.) Entonces el niño puede ejecutar si fue un servicio externo (rlogind, por ejemplo), o tal vez fue uno de los servicios internos de inetd (echo, timeofday) en cuyo caso simplemente hace lo suyo y sale.
No puede hacer eso con "hilo" / "proceso".
Linus