Hace un par de años hice una práctica de sockets, con el típico modelo cliente-servidor donde el servidor da servicio multicliente con fork(). La práctica cumplía los requisitos y los profesores no detectaron problemas.
Realmente la práctica tenía un bug y es que en ocaciones, se quedaban procesos zombies. Realmente el problema es que confie en el código base que nos daban los profesores, que estaba bugeado. Ahora he tenido que reutilizarla para otra asignatura, y ahora ya se cual era el problema.
En sistemas Unix, un proceso puede tener hijos ¬¬, creados mediante fork. Cuando el hijo termina, se envía la señal SIGCHLD al padre. Por defecto, la señal se ignora y se crea un proceso zombie. El padre debe instalar un manipulador de señales para actuar sobre la señal, ese era mi problema. En algunas plataformas Unix, se pueden evitar los zombies explícitamente ignorando la señal SIGCHLD. Sin embargo, instalar un manipulador de señales para SIGCHLD y llamar a wait es la mejor manera de evitar zombies conservando la portabilidad.
El manipulador de la señal:
void sigchld_handler(int s) { while(wait(NULL) > 0); }
Hay varias funciones o métodos para setear la señal, os pongo 2, el largo(más portable, POSIX) y el corto(desconozco su portabilidad):
struct sigaction sa; sa.sa_handler = sigchld_handler; // manejador sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("Error en sigaction"); exit(1); }
Os dejo la forma más corta y fácil:
signal(SIGCHLD , sigchld_handler);
No hace falta decir que necesitais el «signal.h»
Fuentes: http://es.wikipedia.org/wiki/SIGCHLD
Filed under: programación | Tagged: c#, Linux, señales |
Deja una respuesta