You are on page 1of 3

/* EJEMPLO COLAS DE MENSAJES - main() crea 4 hilos (la misma funcin) con un parmetro que indica retardo: 500,

1000, 1500 y 2000 ms. - El hilo main() queda a la espera de la recepcin de mensajes en una cola de 4 posiciones. - Cada uno de los hilos realiza el retardo indicado, y a continuacin enva un mensaje a la cola con un valor entero igual al retardo+contador */ #include <stdio.h> #include <stdlib.h> #include #include #include #include #include <errno.h> <sys/stat.h> <sys/types.h> <fcntl.h> <mqueue.h> "/tmp"

int main() { mode_t mode=0777; struct mq_attr attr; pthread_t hilo2[4]; int interv_h2[4]; int err; int recibido,prio; int i;

// Ojo: est en octal

err=mq_unlink(NOMBRE_COLA_MSG); if (err==-1) { printf("Error borrado cola mensajes: %s\n",strerror(errno)); return 0; } attr.mq_flags=0; attr.mq_maxmsg=4; attr.mq_msgsize=sizeof(int); attr.mq_curmsgs=0; _cola=mq_open(NOMBRE_COLA_MSG,O_CREAT | O_RDWR,mode,&attr); if (_cola==-1) { printf("Error en creacin de nueva cola %s\n",strerror(errno)); exit(0); } for (i=0;i<4;i++) { interv_h2[i]=(i+1)*500; err=pthread_create(&hilo2[i],NULL,HiloEnviaMensajes,&interv_h2[i]); } while (1) { usleep(4000000); err=mq_receive(_cola,(char*) &recibido,sizeof(int),&prio); if (err==-1) { printf("Error recepcin de mensaje: %s\n",strerror(errno)); break; } else printf("RECIBIDO mensaje: %d\n",recibido); } mq_close(_cola); mq_unlink(NOMBRE_COLA_MSG); return 0; }

#define NOMBRE_COLA_MSG mqd_t _cola;

void* HiloEnviaMensajes(void* param) { int intervalo=* ((int*) param); int contador=intervalo; int err; printf("Comienza hilo con intervalo = %d\n",intervalo); while (1) { usleep(intervalo*1000); contador++; err=mq_send(_cola,(char*) &contador,sizeof(int),10000-intervalo); if (err==-1) printf("Error enviando mensaje %d H2%s\n",contador,strerror(errno)); else printf("Mensaje cdigo: %d enviado a la cola\n",contador); } return NULL; }

/* EJEMPLO DE RELOJES, TEMPORIZADORES Y SEALES POSIX El programa main() realiza temporizaciones de 1.5 seg y escribe el tiempo que ha pasado desde el principio del programa. Se pueden compilar 3 casos diferentes: para ello, se define la constante USAR_TEMPORIZACION con el caso deseado. Si USAR_TEMPORIZACION==CASO_SLEEP, la temporizacin se hace con usleep(). Si USAR_TEMPORIZACION==CASO_SINCRONO, se utiliza un temporizador POSIX en modo sncrono. Si USAR_TEMPORIZACION==CASO_ASINCRONO, se utiliza un temporizador POSIX en modo asncrono (aviso mediante seal). */ #define #define #define #define CASO_SLEEP CASO_SINCRONO CASO_ASINCRONO USAR_TEMPORIZACION <stdio.h> <stdlib.h> <time.h> <unistd.h> 1 2 3 CASO_SINCRONO

intervalo_timer.it_value.tv_nsec= 0; intervalo_timer.it_interval.tv_sec=1; intervalo_timer.it_interval.tv_nsec=500000000; err=timer_settime(id_timer,0,&intervalo_timer,NULL);

// Intervalo 1.5 seg

while (cuenta_timer<10) { sigwait(&senyales,&id_senyal); cuenta_timer++; err=clock_gettime(CLOCK_REALTIME,&t_now); diff_tiempo=(t_now.tv_sec-t_ini.tv_sec)+(t_now.tv_nsec-t_ini.tv_nsec)*1e-9; printf("TEMPORIZADOR SINCRONO: %d -> tiempo= %16.8lf\n",cuenta_timer,diff_tiempo); FuncionProcesamiento(1000000); }

#include #include #include #include

err=timer_delete(id_timer); return 0; } #elif USAR_TEMPORIZACION==CASO_ASINCRONO #include <signal.h> #include <pthread.h> volatile int _cuenta_timer=0; volatile struct timespec _t_ini; void { FuncionServicioTemporizador(int signo, siginfo_t *info, void *context) struct timespec t_now; int err; double diff_tiempo; _cuenta_timer++; err=clock_gettime(CLOCK_REALTIME,&t_now); diff_tiempo=(t_now.tv_sec-_t_ini.tv_sec)+(t_now.tv_nsec-_t_ini.tv_nsec)*1e-9; printf("TEMPORIZADOR ASINCRONO: %d -> tiempo= %16.8lf\n",_cuenta_timer,diff_tiempo); FuncionProcesamiento(1000000); }

int FuncionProcesamiento(int n) { int i,x; // Bucle de retardo: for (i=0,x=0;i<n;i++) x=x+1; return x; } #if USAR_TEMPORIZACION==CASO_SLEEP int main() { int err; double diff_tiempo; struct timespec t_ini,t_now; int cuenta_timer_sleep=0; err=clock_gettime(CLOCK_REALTIME,&t_ini); while (cuenta_timer_sleep<10) { cuenta_timer_sleep++; err=clock_gettime(CLOCK_REALTIME,&t_now); diff_tiempo=(t_now.tv_sec-t_ini.tv_sec)+(t_now.tv_nsec-t_ini.tv_nsec)*1e-9; printf("Comienza espera 1.5 seg. Tiempo = %16.8lf\n",diff_tiempo); usleep(1500000); err=clock_gettime(CLOCK_REALTIME,&t_now); diff_tiempo=(t_now.tv_sec-t_ini.tv_sec)+(t_now.tv_nsec-t_ini.tv_nsec)*1e-9; printf("Termina espera 1.5 seg. Tiempo = %16.8lf\n",diff_tiempo); FuncionProcesamiento(1000000); } return 0; } #elif USAR_TEMPORIZACION==CASO_SINCRONO int main() { timer_t id_timer; struct itimerspec intervalo_timer; int cuenta_timer=0; struct timespec t_ini,t_now; sigset_t senyales; int err,id_senyal; double diff_tiempo; err=clock_gettime(CLOCK_REALTIME,&t_ini); err=sigemptyset(&senyales); err=sigaddset(&senyales,SIGALRM); err=pthread_sigmask(SIG_BLOCK,&senyales,NULL); err=timer_create(CLOCK_REALTIME,NULL,&id_timer); // Usar seal por defecto SIGALRM intervalo_timer.it_value.tv_sec=4; // Retardo inicial 4 seg

int main() { timer_t id_timer; struct itimerspec intervalo_timer; struct timespec t_ini; sigset_t senyales; int err,id_senyal; double diff_tiempo; struct sigaction accion_deseada; err=clock_gettime(CLOCK_REALTIME,&_t_ini); err=sigemptyset(&senyales); err=sigaddset(&senyales,SIGALRM); err=pthread_sigmask(SIG_BLOCK,&senyales,NULL); accion_deseada.sa_flags=0; accion_deseada.sa_mask=0; accion_deseada.sa_sigaction=FuncionServicioTemporizador; err=sigaction(SIGALRM,&accion_deseada,NULL); err=pthread_sigmask(SIG_UNBLOCK,&senyales,NULL); err=timer_create(CLOCK_REALTIME,NULL,&id_timer); // Usar seal por defecto SIGALRM intervalo_timer.it_value.tv_sec=0; // Retardo inicial 0 intervalo_timer.it_value.tv_nsec= 100; intervalo_timer.it_interval.tv_sec=1; // Intervalo 1.5 seg intervalo_timer.it_interval.tv_nsec=500000000; err=timer_settime(id_timer,0,&intervalo_timer,NULL); while (getchar()!='X'); err=timer_delete(id_timer); return 0; } #endif

/* Ejemplo de tratamiento de seales y excepciones El programa principal genera un acceso a una posicin de memoria invlida cuando se pulsa INTRO Tambin se puede enviar una seal de usuario SIGUSR1 desde otro proceso (ej. desde lnea de comandos con kill) */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #define BIEN_HECHO_PARA_TR #define MAL_HECHO_PARA_TR #define COMO_ESTA_HECHO 1 2 BIEN_HECHO_PARA_TR

#elif COMO_ESTA_HECHO==BIEN_HECHO_PARA_TR #include <setjmp.h> sigjmp_buf _env; void ErrorViolacionDeSegmento(int num_senyal, siginfo_t *info_senyal, void *no_usar) { if (num_senyal==SIGSEGV) { printf("<<<Error violacion de memoria>>>\n"); siglongjmp(_env,27); } else if (num_senyal==SIGUSR1) { printf("<<<Recibida seal de USUARIO >>>\n"); return; } else printf("Seal numero %d recibida\n",num_senyal); } int main() { sigset_t senyales; int err; struct sigaction accion_violacion_segmento; int x[2]; char c; err=sigemptyset(&senyales); err=sigaddset(&senyales,SIGSEGV); err=sigaddset(&senyales,SIGUSR1); err=pthread_sigmask(SIG_BLOCK,&senyales,NULL); accion_violacion_segmento.sa_flags=0; accion_violacion_segmento.sa_sigaction=ErrorViolacionDeSegmento; accion_violacion_segmento.sa_mask=0; err=sigaction(SIGSEGV,&accion_violacion_segmento,NULL); err=sigaction(SIGUSR1,&accion_violacion_segmento,NULL); err=pthread_sigmask(SIG_UNBLOCK,&senyales,NULL); printf("Pulsa \'X\' para generar excepcion SIGSEGV: "); while (getchar()!='X'); if (sigsetjmp(_env,1)==0) { x[0]=100; printf("x[0]=%d. Ok\n",x[0]); fflush(stdout); x[1]=100; printf("x[1]=%d. Ok\n",x[1]); fflush(stdout); x[1000000]=100; printf("x[1000000]=%d. Ok\n",x[1000000]); fflush(stdout); } else { printf("Retornando de excepcion y terminando programa de forma controlada\n"); } fflush(stdin); getchar(); return 1;

#if COMO_ESTA_HECHO==MAL_HECHO_PARA_TR void ErrorViolacionDeSegmento(int num_senyal, siginfo_t *info_senyal, void *no_usar) { if (num_senyal==SIGSEGV) { printf("<<<Error violacion de memoria>>>\n"); exit(-1); } else if (num_senyal==SIGUSR1) { printf("<<<Recibida seal de USUARIO >>>\n"); return; } else printf("Seal numero %d recibida\n",num_senyal); } int main() { sigset_t senyales; int err; struct sigaction accion_violacion_segmento; int x[2]; char c; err=sigemptyset(&senyales); err=sigaddset(&senyales,SIGSEGV); err=sigaddset(&senyales,SIGUSR1); err=pthread_sigmask(SIG_BLOCK,&senyales,NULL); accion_violacion_segmento.sa_flags=0; accion_violacion_segmento.sa_sigaction=ErrorViolacionDeSegmento; accion_violacion_segmento.sa_mask=0; err=sigaction(SIGSEGV,&accion_violacion_segmento,NULL); err=sigaction(SIGUSR1,&accion_violacion_segmento,NULL); err=pthread_sigmask(SIG_UNBLOCK,&senyales,NULL); printf("Pulsa \'X\' para generar excepcin SIGSEGV: "); while (getchar()!='X'); x[0]=100; printf("x[0]=%d. Ok\n",x[0]); fflush(stdout); x[1]=100; printf("x[1]=%d. Ok\n",x[1]); fflush(stdout); x[1000000]=100; printf("x[10000000]=%d. Ok\n",x[1000000]); fflush(stdout); fflush(stdin); getchar(); return 1; }

} #endif

You might also like