Procesos vs Hilos

Iniciado por SDCC, 3 Septiembre 2019, 06:20 AM

0 Miembros y 1 Visitante están viendo este tema.

SDCC

Buenas a todos, actualmente estoy revisando el libro de Sistemas Operativos , Silberschatz Galvin Gagne y me ha surgido una duda con referencia al uso que se le pueden dar tanto a los procesos como a los hilos. Entiendo el concepto tanto de hilos y procesos sin embargo no llego a entender la finalidad de poder crear varios procesos. Tal vez suene un poco tonto pero no he encontrado un ejemplo claro en donde vea una ventaja o necesidad de crear varios procesos dentro de una misma computadora y crear una linea de comunicacion entre ellos a la contraparte de generar hilos.

En el libro se enfoca mucho en el hecho de que los hilos son mas rapidos de construir en el sentido de que se encuentran dentro de un mismo proceso y pueden compartir facilmente informacion. Ademas se explica un poco como es posible sacarle provecho para que cada hilo pueda ser ejecutado por un nucleo distinto y que cada uno tenga una actividad especifica dentro del programa. Este concepto de poder utilizar varios nucleos y ejecutar varios hilos en paralelo con ayuda de varios nucleos es posible tambien con los procesos?, he leido que en linux todo (hilo,procesos) es tomado como proceso pero el mismo concepto se ve reflejado en sistemas de windows?.

Finalmente me gustaria saber  si alguien me podria proporcionar un ejemplo claro en el que es util tener varios procesos en paralelo en contraparte de por que no se podria hacer con hilos?. Me gustaria tener alguna referencia o guia que trate estos temas de una manera mas practica a traves del lenguaje C/C++ para reforzar la teoria, si alguien conoce alguna se lo agradeceria de antemano.


kub0x

Cita de: SDCC en  3 Septiembre 2019, 06:20 AM
Este concepto de poder utilizar varios nucleos y ejecutar varios hilos en paralelo con ayuda de varios nucleos es posible tambien con los procesos?

Si es posible aunque un context switch es mucho más caro realizarlo en el caso de los procesos en vez de los threads ya que cuando se realiza con un proceso ha de cambiar el espacio de memorias virtual entre otros y en el caso de los thread no sucede, simplemente se cambian los registros pertinentes al stack y demás.

Ahora para darte un ejemplo sobre utilización de procesos en paralelo en vez de usar hilos, pues no lo veo muy recomendable te pongo en posibles situaciones:

Imagina que tienes 4 CPUs equivaldría a un proceso por cada una de estas (paralelo). Cada CPU tiene un sistema de memorias caches, y al correr en paralelo, sucede que si no se migra ninguno de los procesos a otra CPU distinta, al cambiar de contexto en cada CPU sea mejor ya que la cache coherency se mantiene. Pero quizá se pueda hacer este esquema sólo con threads y mantener la coherencia, entonces no sería mejor usar procesos aquí, todo depende del scheduler así que yo iría por los threads.

En Linux existe la variante fork() que hace un child y mantiene la referencia al parent, así el padre reconoce al hijo y el hijo al padre y te permite saber que instancia de código correr. También tienes pthread para utilizar un thread como tal.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


SDCC

Entonces al parecer cuando se habla de paralelismo la opcion mas viable siempre es la de los hilos pero que razon de ser pueden tener la creacion de procesos a partir de un padre?. He visto un poco las funciones fork,wait,exec,etc.. Y comprendo que la generacion de un nuevo proceso permite crear esa jerarquia de hijos-padre pero realmente hasta ese punto aun no se esta hablando sobre paralelismo, verdad?. Entonces que sentido tendria crear varios procesos de esta manera que pudiera presentar una ventaja conforme a los hilos. O este proceso es heredado por codigo que fue desarrollado desde antes de la existencia de hilos y ya solo es visto como contenido educativo?.

Como un punto y aparte me surge la duda de si el planificador de procesos de corto plazo de linux hace uso de los varios nucleos disponibles en la computadora. He visto varios puntos de vista en donde algunos hablan de la insercion de los PCB en arboles ordenados conforme a su tiempo en CPU que se les ha dado, mientras que algunos otros lados se enfocan mas en explicar que se trata de un mapa de bits con cada prioidad en donde cada posicion se encuentra almacenados los procesos con dicha prioridad pero mi principal duda surge en el momento de que se usan los distintos nucleos para la parte de la planificacion, he leido sobre el hecho de que esto puede ser implementado de distintas maneras como por ejemplo a traves de un nucleo maestro,etc. Pero en Linux se implementa esta forma de utilizar varios nucleos en la planifacion? y en dado caso que llega a pasar cuando el planificador funciona con varios nucleos y llega un proceso que tiene varios hilos y requiere paralelismo?. Se comparten los nucleos entre el planificador y ese nuevo proceso con hilos o se le da todos los nucleos momentaneamente al proceso con varios hilos?

MinusFour

Cita de: SDCC en  3 Septiembre 2019, 23:06 PM
Entonces al parecer cuando se habla de paralelismo la opcion mas viable siempre es la de los hilos pero que razon de ser pueden tener la creacion de procesos a partir de un padre?. He visto un poco las funciones fork,wait,exec,etc.. Y comprendo que la generacion de un nuevo proceso permite crear esa jerarquia de hijos-padre pero realmente hasta ese punto aun no se esta hablando sobre paralelismo, verdad?. Entonces que sentido tendria crear varios procesos de esta manera que pudiera presentar una ventaja conforme a los hilos. O este proceso es heredado por codigo que fue desarrollado desde antes de la existencia de hilos y ya solo es visto como contenido educativo?.

Como usuario, tienes más control sobre tus procesos. Por ejemplo, puedes matar un proceso que se quede ciclado. Le puedes cambiar la afinidad (o su niceness) al proceso. Puedes cambiar permisos al proceso, etc. Tengo entendido que lo puedes hacer desde el contexto del proceso pero no es algo que un proceso externo pueda cambiar. Con los threads tienes la ventaja que son ligeros pero también incrementas la complejidad de tu programa para sincronizar el acceso a al memoria.

Cita de: SDCC en  3 Septiembre 2019, 23:06 PM
Como un punto y aparte me surge la duda de si el planificador de procesos de corto plazo de linux hace uso de los varios nucleos disponibles en la computadora. He visto varios puntos de vista en donde algunos hablan de la insercion de los PCB en arboles ordenados conforme a su tiempo en CPU que se les ha dado, mientras que algunos otros lados se enfocan mas en explicar que se trata de un mapa de bits con cada prioidad en donde cada posicion se encuentra almacenados los procesos con dicha prioridad pero mi principal duda surge en el momento de que se usan los distintos nucleos para la parte de la planificacion, he leido sobre el hecho de que esto puede ser implementado de distintas maneras como por ejemplo a traves de un nucleo maestro,etc. Pero en Linux se implementa esta forma de utilizar varios nucleos en la planifacion? y en dado caso que llega a pasar cuando el planificador funciona con varios nucleos y llega un proceso que tiene varios hilos y requiere paralelismo?. Se comparten los nucleos entre el planificador y ese nuevo proceso con hilos o se le da todos los nucleos momentaneamente al proceso con varios hilos?

Para efectos de planificación, hasta donde yo tengo entendido, los procesos y threads son indistinguibles. No veo porque no se puedan paralelizar multiples procesos de un solo thread.

SDCC

Cita de: MinusFour en  4 Septiembre 2019, 00:43 AM
Para efectos de planificación, hasta donde yo tengo entendido, los procesos y threads son indistinguibles. No veo porque no se puedan paralelizar multiples procesos de un solo thread.

En esta parte tal vez no me explique muy bien. Quisiera hacer referencia al planificador como tal, por ejemplo:
El planificador tiene un 'X' algoritmo pero resulta que utiliza todos los procesadores para distribuir los diversos procesos en la cola de lista entre los diversos nucleos. Para ser mas concreto podria ser que existieran 4 nucleos:
1 Nucleo. Es el nucleo maestro, es el unico que tiene acceso a la cola de procesos listos y le asigna a cada uno de los otros 3 nucleos un conjunto de esos procesos listos.
2,3,4 Nucleo. Solo ejecutan procesos que le son pasados por el nucleo maestro.

En este caso o en algoritmos donde se haga uso de todos los nucleos para la planificacion de una forma parecida que succede si entra un proceso que tiene 4 hilos en paralelo en un mismo instante de tiempo?. Supongamos que este proceso estaba destinado para estar en el nucleo 2 pero esta requiriendo hilos a nivel de kernel. En ese caso cambia todo el algoritmo de planificacion para que ahora 2 procesos se queden despachando procesos y los otros dos nucleos intenten satisfacer los hilos de dicho proceso o simplemente es rechazada su paralelismo y se le asigna un unico nucleo para todos sus hilos. Aclarando que ese cambio va ser solo una porcion de segundo(quantum). O definitivamente no se usa este tipo de estructura para sistemas operativos que permiten el paralelismo en hilos/procesos.

MinusFour

Cita de: SDCC en  4 Septiembre 2019, 01:20 AM
En esta parte tal vez no me explique muy bien. Quisiera hacer referencia al planificador como tal, por ejemplo:
El planificador tiene un 'X' algoritmo pero resulta que utiliza todos los procesadores para distribuir los diversos procesos en la cola de lista entre los diversos nucleos. Para ser mas concreto podria ser que existieran 4 nucleos:
1 Nucleo. Es el nucleo maestro, es el unico que tiene acceso a la cola de procesos listos y le asigna a cada uno de los otros 3 nucleos un conjunto de esos procesos listos.
2,3,4 Nucleo. Solo ejecutan procesos que le son pasados por el nucleo maestro.

¿Donde leíste esto? Los procesos no van en los núcleos hasta donde yo tengo entendido. Los procesos son artefactos de los sistemas operativos.

Cita de: SDCC en  4 Septiembre 2019, 01:20 AMEn este caso o en algoritmos donde se haga uso de todos los nucleos para la planificacion de una forma parecida que succede si entra un proceso que tiene 4 hilos en paralelo en un mismo instante de tiempo?. Supongamos que este proceso estaba destinado para estar en el nucleo 2 pero esta requiriendo hilos a nivel de kernel. En ese caso cambia todo el algoritmo de planificacion para que ahora 2 procesos se queden despachando procesos y los otros dos nucleos intenten satisfacer los hilos de dicho proceso o simplemente es rechazada su paralelismo y se le asigna un unico nucleo para todos sus hilos. Aclarando que ese cambio va ser solo una porcion de segundo(quantum). O definitivamente no se usa este tipo de estructura para sistemas operativos que permiten el paralelismo en hilos/procesos.

Aquí no te entendí NADA. Lo único que alcance a entender más o menos es que estás preocupado por la estrategia del planificador que ponga todos tus hilos a trabajar en un solo núcleo. Y lo puede hacer, dependiendo de la estrategia. Pero no tiene nada que ver si es un proceso o un thread o un kernel thread.

kub0x

Al fin y al cabo lo que buscas es que el scheduler haga un trade-off entre responsiveness y performance. Como bien sabes un sistema operativo tiene una carga brutal de balance ya que tiene que realizar seguimiento de todo lo que está conectado en ese momento al sistema, así como todos los mensajes del OS, irqs de hardware y súmale luego lo que tu estés computando entre mientras más otras tareas habituales como utilizar software (navegadores, multimedia, etc). Quiero decir que un PC no es el entorno ideal para ejecutar computo paralelo si es que el PC no está perfectamente diseñado para ello, el scheduler es la pieza que regula todas estas actividades y lo puedes monitorizar en Linux a tu placer (busca como hacerlo).

Lo suyo es que crearás un entorno hardware en el que poder describir todo lo que necesitas y se ejecute nada más lo que necesitas. Sino lo ideal también es hacer cómputo distribuido en red e implementar políticas de scheduling en usermode para hacer un override a kernel en ciertos paramétros que conciernen tu aplicación. Lo ideal es que hagas un grafo de dependencias para después hacer un Thread manager que despache tus tareas de modo eficiente, así ningún hilo se queda dormido o esperando IO (polling). Estos grafos deben ser acíclicos, si se detecta un ciclo es que existe una dependencia circular (A->B->C->A) y no podrías ejecutarlas. De esta forma cuando termina una tarea se despacha otra, ahora quizá las tareas necesiten información común, ahí entra en juego la coherencia de cache y la migración entre cores. Es un tema complejo, y realmente se utilizan hilos como unidades de ejecucción. Dime que es lo que realmente buscas y podré pasarte papers sobre el tema.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


SDCC

Cita de: kub0x en  4 Septiembre 2019, 10:46 AM
Es un tema complejo, y realmente se utilizan hilos como unidades de ejecucción. Dime que es lo que realmente buscas y podré pasarte papers sobre el tema.

Inicialmente mi pregunta es si en la actualidad tenia alguna utilidad evidente el utilizar la creacion de procesos a traves de llamados al sistema como fork,exec,etc.. Creo que esta respuesta la ire obteniendo conforme vaya poniendo en practica estos conceptos en algun programa que es lo que actualmente estoy haciendo.

Como segunda pregunta tenia una duda con referencia a la planifcacion en sistemas con procesadores multiples para lo cual voy a escribir un segmento del libro donde lei sobre el tema
Citar
Si se dispone de multiples CPU, el problema de planifacion , es complejo...........................
Algunos sistemas estra estructura un paso mas alla, haciendo que todas las decisiones de planifacion,el procesamiento de E/S y otras actividades del sistema sean maneajdas por un solo procesador-el servidor maestro.Los otros procesadores solo ejecutan codigo de usuario.este multiprocesamineto asimetrico es mucho mas sencillo al simetrico.............
Cita obtenida del Libro de Sistemas Operativos 6a. Edicion, Silberschatz Galvin Gagne. Pag. 153

Aqui es donde me surge una duda.. Esta explicacion es clara cuando los procesos que se trabajan son de un solo hilo..Pero cuando se ingresa un proceso con varios hilos como es que se procesa?. Solamente se le asigna finalmente un nucleo a ese proceso y no permite que cada hilo se procese en distintos nucleos en paralelo o les qutia la carga de trabajo a una parte de los nucleos y les asigna como trabajo un hilo mientras se encuentra en CPU el proceso que lo requiere, cuando se le acaba la rafaga todo vendria a volver a la normalidad. Y finalmente intuyo que estos conceptos son muy teoricos y que por lo general en la practica no se ve la estructura como tal , sino una combinacion de varias formas de hacerlo pero que tan cercana es la situacion en LINUX, es decir, en LINUX se toma un enfoque de planificacion con varios multiprocesadores o simplemente se utiliza 1 para esta tarea y cuando un proceso demanda varios hilos se activan los demas nucleos?.

Se que tal vez son dudas un poco tontas pero he empezado hace unas pocas semanas con el tema y me he topado con mucha informacion pero con poca practica donde pueda reforzar la teoria. Actualmente estoy leyendo el libro Silberschatz y hace unos dias comence con el libro de Interprocess Communications in Linux de John Shapley Gray que me parece que es un libro con mas practicas.

kub0x

#8
Cita de: SDCC en  7 Septiembre 2019, 02:14 AM
Inicialmente mi pregunta es si en la actualidad tenia alguna utilidad evidente el utilizar la creacion de procesos a traves de llamados al sistema como fork,exec,etc.. Creo que esta respuesta la ire obteniendo conforme vaya poniendo en practica estos conceptos en algun programa que es lo que actualmente estoy haciendo.

Ten en cuenta que fork() crea un child process, por lo tanto el kernel mapea un espacio de memoria para este nuevo PROCESO, para nada es un hilo. Al thread se le llama sibling en vez de child. Lo que pasa que la arquitectura que ofrece Unix sobre los elementos derivados de fork() permite una interacción child-parent bastante eficiente y puede ser buena en algunos escenarios especialmente cuando ambos procesos hacen cosas parecidas, visto desde la programación, ahorras escribir el código en forma de thread por lo tanto ahorras la sync entre hilos y el main thread (hilo principal del proceso). Esto es recomendable que lo pruebes con un código sencillito detectando cuando estás en parent o child y descencadenando las pertinentes acciones.

Cita de: SDCC en  7 Septiembre 2019, 02:14 AM
Pero cuando se ingresa un proceso con varios hilos como es que se procesa?. Solamente se le asigna finalmente un nucleo a ese proceso y no permite que cada hilo se procese en distintos nucleos en paralelo o les qutia la carga de trabajo a una parte de los nucleos y les asigna como trabajo un hilo mientras se encuentra en CPU el proceso que lo requiere, cuando se le acaba la rafaga todo vendria a volver a la normalidad. Y finalmente intuyo que estos conceptos son muy teoricos y que por lo general en la practica no se ve la estructura como tal , sino una combinacion de varias formas de hacerlo pero que tan cercana es la situacion en LINUX, es decir, en LINUX se toma un enfoque de planificacion con varios multiprocesadores o simplemente se utiliza 1 para esta tarea y cuando un proceso demanda varios hilos se activan los demas nucleos?.

Se que tal vez son dudas un poco tontas pero he empezado hace unas pocas semanas con el tema y me he topado con mucha informacion pero con poca practica donde pueda reforzar la teoria. Actualmente estoy leyendo el libro Silberschatz y hace unos dias comence con el libro de Interprocess Communications in Linux de John Shapley Gray que me parece que es un libro con mas practicas.

A pesar de que la tecnología multi-core es "reciente" el cómputo y los algoritmos distribuidos llevan cuantiosas décadas siendo desarrollados, el tema es complejo, son muchas las posibilidades y los escenarios que pueden darse en un entorno paralelo. Escribo lo que encuentro más importante para este tema:

Una vez que el programa EFI cargue el bootloader, en la fase de arranque del kernel se mapea entre otras la tabla de interrupciones del sistema, que no son más que unos punteros a funciones syscall que más tarde el kernel utilizará mediante interrupciones (IRQ). Cierto proceso o módulo kernel pueden llamar estas funciones sin problemas mandando una interrupción software/hardware. Sucede que la CPU realiza un cambio de contexto situando el proceso/hilo responsable de la IRQ en la unidad de ejecucción.

Aquí entra el balanceo del scheduler. Imagina un proceso multi-hilo.  Si se terminó la ejecucción antes de que se agote el time-slice, es obvio que pasa a ejecutar la próxima tarea (que estará en el hilo X) y el hilo anteriormente ejecutado pasa a sleep o I/O (bloqueado) o bien se destruye y el scheduler borra las dependencias. Si el slice hizo timeout, guarda el contexto con el estado de la tarea y cambia a la siguiente tarea-hilo. Lo más importante es que cuando acabe la ejecucción de un hilo, no se destruya, ya que es innecesario hacerlo, es mejor mantener una lista de X hilos e ir insertando las tareas en runtime con tu propio dispatcher.

En Linux podrás decirle al scheduler (usermode) incluso en que CPUs quieres la ejecucción de cada hilo. Es verdad que luego toda la lógica está en kernel pero incluso puedes reescribirla (todo es posible en Linux). Para mí lo más importante de este esquema es la arquitectura NUMA y la coherencia de cache. Como dije anteriormente, utilizando teoría de grafos puedes determinar el modelo de dependencias entre tareas y así hacer tu programa determinista en relación al esquema de dichas tareas, por lo tanto hacer un dispatcher que las ordene por CPU y se encargue en runtime de ir mapeando la tarea i en la CPU j teniendo en cuenta todo lo anteriormente dicho. Es un non-blocking thread model pero en paralelo.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


MinusFour

Cita de: SDCC en  7 Septiembre 2019, 02:14 AM
Inicialmente mi pregunta es si en la actualidad tenia alguna utilidad evidente el utilizar la creacion de procesos a traves de llamados al sistema como fork,exec,etc.. Creo que esta respuesta la ire obteniendo conforme vaya poniendo en practica estos conceptos en algun programa que es lo que actualmente estoy haciendo.

Todos los procesos son forks de otros procesos en Linux. Si quieres empezar un nuevo proceso, la única forma es clonar un proceso e inicializar un programa. Esa es la utilidad de fork y exec. Esa es la forma en la que una shell empieza un nuevo proceso por ejemplo, se clona a si mismo y carga el programa.

Al final, lo que tu pareces es estar discutiendo es usar multiples procesos vs multiples threads para efectos de paralelización.