senales
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
senales [2012/10/01 14:39] – lmateu | senales [2016/11/24 13:13] (actual) – [sigaction/sigprocmask] lmateu | ||
---|---|---|---|
Línea 76: | Línea 76: | ||
/* Leer una línea del teclado dándole 10 segundos de plazo */ | /* Leer una línea del teclado dándole 10 segundos de plazo */ | ||
#include < | #include < | ||
- | #undef __USE_BSD /* para que el read pueda ser interrumpido por una seal */ | + | #undef __USE_BSD /* para que el read pueda ser interrumpido por una señal |
#include < | #include < | ||
#include < | #include < | ||
Línea 82: | Línea 82: | ||
volatile int flag; | volatile int flag; | ||
| | ||
- | /* función para atrapar la seal de alarma */ | + | /* función para atrapar la señal |
void ring() { | void ring() { | ||
flag=0; | flag=0; | ||
Línea 140: | Línea 140: | ||
} | } | ||
- | int call_with_timeout(int (*f)(), int timeout) | + | int call_with_timeout(int (*f)(void *), void *p, int timeout) |
{ | { | ||
int res; | int res; | ||
Línea 154: | Línea 154: | ||
alarm(timeout); | alarm(timeout); | ||
- | res = f(); | + | res = f(p); |
printf(" | printf(" | ||
alarm(0); | alarm(0); | ||
Línea 162: | Línea 162: | ||
} | } | ||
- | int fun() { | + | int fun(void *p) { |
sleep(2); | sleep(2); | ||
return 0; | return 0; | ||
Línea 168: | Línea 168: | ||
int main() { | int main() { | ||
- | call_with_timeout(fun, | + | call_with_timeout(fun, NULL, 1); |
- | call_with_timeout(fun, | + | call_with_timeout(fun, NULL, 1); |
return 0; | return 0; | ||
} | } | ||
Línea 195: | Línea 195: | ||
... | ... | ||
| | ||
- | int call_with_timeout(int (*f)(), int timeout) { | + | int call_with_timeout(int (*f)(void *), void *p, int timeout) { |
... | ... | ||
if (sigsetjmp(ring, | if (sigsetjmp(ring, | ||
Línea 207: | Línea 207: | ||
POSIX sí la define. | POSIX sí la define. | ||
+ | === Discusión === | ||
+ | |||
+ | Otro punto importante que no se debe olvidar es lo que pasa con los recursos solicitados por la | ||
+ | función. | ||
+ | jamás y por lo tanto se transforman en goteras. | ||
+ | una traza de todos los recursos pedidos para así liberarlos cuando se cumpla el timeout. | ||
+ | no es trivial de hacer. | ||
+ | |||
+ | También hay que considerar que la invocación de la rutina que atiende la señal puede provocar dataraces. | ||
+ | Por ejemplo supongamos que la función f usa malloc. | ||
+ | del malloc y por lo tanto el heap que maneja malloc queda en un estado inconsistente. | ||
+ | la señal también invoca malloc, se puede producir una inconsistencia que gatille un segmentation fault o | ||
+ | que se entregue 2 veces el mismo pedazo de memoria. | ||
+ | señal deben ser simples como asignar una variable global por ejemplo. | ||
==== sigaction/ | ==== sigaction/ | ||
Línea 218: | Línea 232: | ||
* etc. | * etc. | ||
- | Del mismo modo, sigprocmask permite deshabilitar/ | + | Del mismo modo, sigprocmask permite deshabilitar/ |
+ | para resolver el datarace asociado al uso de malloc tanto en el código en donde puede ocurrir una señal como en la función | ||
+ | que atiende esa señal. | ||
+ | invocar nuevamente sigprocmask para reactivar nuevamente la señal. | ||
+ | malloc, la señal quedará pendiente y solo se invocará la rutina de atención cuando se reactive la señal en la | ||
+ | segunda llamada de sigprocmask. | ||
Consulte la página del manual para averiguar más sobre estas funciones. | Consulte la página del manual para averiguar más sobre estas funciones. | ||
+ | |||
+ | ==== Ejercicio ==== | ||
+ | |||
+ | Resuelva la parte c de la pregunta 1 del [[http:// |
senales.1349102377.txt.gz · Última modificación: 2012/10/01 14:39 por lmateu