martes, 9 de marzo de 2010

SETSID Y SCHED_YIELD

CREACION DE SECIONES SETSID()

NOMBRE
setsid - crea una sesión y define el ID de grupo del proceso


SINOPSIS
#include <unistd.h>

pid_t setsid(void);

DESCRIPCION

setsid() crea una nueva sesión si el proceso que realiza la llamada no es lider de grupo de procesos. El proceso que realiza la llamada es lider de la nueva sesión, lider de grupo de procesos del nuevo grupo de procesos, y no tiene terminal controladora. El ID del grupo de procesos y el ID de la sesion del proceso que realiza la llamada se ponen al PID del proceso que realiza la llamada. Dicho proceso será el único proceso en este nuevo grupo de procesos y en esta nueva sesión.

VALOR DEVUELTO

El ID de la sesión del proceso que realiza la llamada.

ERRORES

Si hubo error, se devuleve -1. El único error que puede suceder es EPERM. Se devuelve cuando el ID del grupo de procesos de cualquier proceso es igual al PID del proceso que realiza la llamada. De este modo,en particular, setsid falla si el proceso que realiza la llamada ya es lider de grupo de procesos.

OBSERVACIONES

El lider de grupo de procesos es un proceso con el ID de grupo igual a su PID. Para asegurarse de que setsid tenga éxito, cree un proceso hijo con fork y termine, y deje que el hijo ejecute setsid().



Descripción de Funcionalidad
– Todo proceso es miembro de un grupo de procesos y todo grupo de procesos es miembro de una sesión.
– Un grupo de procesos tiene un líder cuyo PID es idéntico a su PGID.
– Una sesión tiene un líder y un terminal de control.
– Las señales de teclado son enviadas a todos los procesos de la sesión.
– setsid: crea una nueva sesión y un nuevo grupo cuyo líder es el proceso que la invoca.
– setpgid: cambia el proceso hijo cuyo identificador es pid al grupo pgid.

Ejemplo:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>

main()
{
/// Los identificadores de procesos.
pid_t pid, sid;
// Se crea un proceso hijo (concurrente).
pid = fork();
// Se verifica que se haya creado satisfactoriamente.
if (pid < 0) {
exit(EXIT_FAILURE);
} else if (pid > 0) {
/// Si es el proceso padre, se sale del programa
printf("se creo el proceso hijo\n");
exit(EXIT_SUCCESS);
}
// Usando setsid, separa el proceso y pone el demonio dentro
// una nueva sesion
sid = setsid();
if (sid < 0) {
exit(EXIT_FAILURE);
}else if (sid > 0){
printf("inicia nueva seccion\n");
}
// A partir de aqui comienza el codigo del demonio
while (1) {
printf("Corriendo demonio este mensaje aparecera cada 10 segundos\n");
sleep(10);
}
exit(EXIT_SUCCESS);
}



La llamada de sistema sched yield()
Dentro de una aplicación distribuida es difícil decir el momento en el que un hilo va a entrar en ejecución. En algunas aplicaciones se necesita una ejecución de las partes involucradas. Por tandem entendemos el hecho de que un hilo ejecuta una instrucción para después dejar el CPU y permitir que otro hilo ejecute también una instrucción. Después de ejecutar su instrucción, este último deja el CPU y permite que el primero ejecute otra.
La llamada de sistema que nos permite realizar lo anterior es sched_yield(). El proceso y/o hilo que ejecuta dicha llamada interrumpe su ejecución y se coloca a la cabeza de la lista de procesos listos. En el momento en que el proceso interrumpe su ejecución, el CPU le es asignado al proceso que estaba a la cabeza de la lista de procesos listos. En hilos esto ocurre hasta que los hilos con la misma o mayor prioridad terminan de ejecutar o son bloqueados.
La sintaxis de la llamada es:

#include <sched.h>
int sched_yield(void)

Como se puede constatar no recibe parámetro alguno. La llamada regresa 0 en caso de éxito y regresa -1 si hubo algún error.
Un ejemplo de uso es el siguiente:

#include <pthread.h>
#include <sched.h>

#define SUMSIZE 5
void *f1()
{
int i;
15
for (i = 1; i <= SUMSIZE; i++) {
printf("Soy el thread %d con i: %d \n",pthread_self(),i);
sched_yield();
}
return NULL;
}
void *f2()
{
int i;
for (i = 1; i <= SUMSIZE; i++) {
printf("\t Soy el hilo %d con i: %d \n",pthread_self(),i);
sched_yield();
}
return NULL;
}
main()
{
pthread_t thd1, thd2;
printf("\nEJEMPLO EJECUCION EN TANDEM \n\n");
pthread_create(&thd1, NULL,(void *)f1, NULL);
pthread_create(&thd2, NULL,(void *)f2, NULL);
pthread_join(thd1, NULL);
pthread_join(thd2, NULL);
printf("\nFIN DEL EJEMPLO \n");
}
Consideremos que un hilo ejecuta la función f1() y que otro hilo ejecuta f2(). Cada iteración dentro del ciclo definido en las funciones será ejecutada por un hilo a la vez. La salida del código anterior se muestra a continuación:

EJEMPLO EJECUCION EN TANDEM
Soy el hilo 4 con i: 1
Soy el hilo 5 con i: 1
Soy el hilo 4 con i: 2
Soy el hilo 5 con i: 2
Soy el hilo 4 con i: 3
Soy el hilo 5 con i: 3
Soy el hilo 4 con i: 4
Soy el hilo 5 con i: 4
Soy el hilo 4 con i: 5
Soy el hilo 5 con i: 5
FIN DEL EJEMPLO

No hay comentarios:

Publicar un comentario