mihaispr
Administrator
Inregistrat: acum 16 ani
Postari: 2142
|
|
//Programe pentru blocarea semnalelor
//Program pentru blocarea semnalului SIGTSTP(semnal generat prin apasarea tastei SUSP=CTRL+Z)
#include <stdio.h> #include <signal.h> #include "my_sleep.h"
volatile sig_atomic_t flag = 0; volatile sig_atomic_t nr_semnale_primite = 0; /* În signal.h este definitia: typedef int sig_atomic_t; Declaratia volatile specifica compilatorului ca variabila poate fi modificata asincron (la momente imprevizibile), pentru a nu face optimizari.*/ /* handler-ul propriu de semnal pentru SIGTSTP */
void my_handler(int nr_sem) { /* recoruperea semnalului */ signal(nr_sem, my_handler); nr_semnale_primite++; flag = 1; /* actiuni dorite de utilizator */
printf("Executie handler de semnal SIGTSTP.\n" ); pauza_v2(3,"In handler-ul de SIGTSTP..." ); printf("Sfirsit executie handler de semnal SIGTSTP.\n" ); }
void main() {sigset_t block_stop; int nr_testari_in_main = 0; /* coruperea semnalului SIGTSTP */
signal(SIGTSTP, my_handler); printf("Inceput portiune de cod pe care ^Z este corupt...\n" ); /* initializarea setului de semnale */ sigemptyset(&block_stop); sigaddset(&block_stop, SIGTSTP); while(nr_testari_in_main < 5) { /* început portiune de cod pe care SIGTSTP este blocat*/ sigprocmask(SIG_BLOCK, &block_stop, NULL); /* verifica daca a venit un semnal SIGTSTP, si în caz afirmativ reseteaza flag-ul */ if(flag) { /* activitati dorite daca a fost receptionat semnalul ... */ nr_testari_in_main++; printf("Pâna acum s-au receptionat %d semnale SIGTSTP", nr_semnale_primite); printf(" si s-au facut %d testari in main().\n", nr_testari_in_main); /* resetarea flagului */ flag=0; } sigprocmask(SIG_UNBLOCK, &block_stop, NULL); /* sfârsit portiune de cod pe care SIGTSTP este blocat */ printf("Genereaza semnale SIGTSTP prin apasarea tastelor CTRL+Z !\n" ); /* ... eventual alte actiuni, ce pot fi întrerupte de SIGTSTP */ } printf("Sfirsit portiune de cod pe care ^Z este corupt.\n" ); // refacerea comportamentului implicit pentru acel semnal signal(SIGTSTP, SIG_DFL); sleep(2); printf("Sfirsit program.\n" ); }
/*Acest prim program cuprinde si fisierul header my_sleep.h(fisier cu diferite functii de tipul sleep*/
#ifndef __MY_SLEEP_H #define __MY_SLEEP_H
#include <unistd.h> #include <stdio.h> //#include <signal.h> #include <sys/time.h>
/* Partea 1: Declaratii de functii (interfete)*/
void my_sleep1sec();/* Efect: o pauza de o secunda, activa: implementata prin niste for-uri, nu cu suspendare prin apel de sleep(); Obs: este aprox. 1 sec., deoarece depinde de gradul de încarcare al sistemului la momentul executiei ! */
void pauza_v1(int n, char* msg); /* Efect: se executa o pauza de n secunde, iar la fiecare secunda se afiseaza mesajul msg + timpul: 0, 1, 2, ..., n. Motivul: acesta este comportamentul functiei sleep() : este întrerupta la primirea vreunuia dintre semnalele ce nu sunt ignorate, returnând câte secunde mai avea de asteptat. Din acest motiv, functia s-ar putea sa returneze mai înainte de n sec. ! */
void pauza_v2(int n, char* msg); /* Efect: la fel ca si pauza_v1(), dar în loc de sleep(1); foloseste my_sleep1sec(); */
/* Partea 2: Definitii de functii (implementari)*/
void pauza_v1(int n, char* msg) { int i; if(msg) printf("%s ",msg); printf("Timer: 0\n" ); for(i=0; i<n; i++) { sleep(1); if(msg) printf("%s ",msg); printf("Timer: %d\n",i+1); } }
void pauza_v2(int n, char* msg) { int i; if(msg) printf("%s ",msg); printf("Timer: 0\n" ); for(i=0; i<n; i++) { my_sleep1sec(); if(msg) printf("%s ",msg); printf("Timer: %d\n",i+1); } }
void my_sleep1sec() /*Efect: o pauza de o secunda, activa: implementata prin niste for-uri, nu cu apel de sleep(); Obs: este aprox. 1 sec., deoarece depinde de gradul de încarcare al sistemului la momentul executiei ! */ {
#define T1 135L #define T2 1000L #define T3 1000L
/* #define TEST_Ts // testare diverse valori pentru T1,... si afisare timpi*/ long i,j,k;
#ifdef TEST_Ts struct timeval tv_begin, tv_end; long delta_sec, delta_usec;
gettimeofday( &tv_begin, NULL);
printf("Begin time: %d sec : %d microsec\n", tv_begin.tv_sec, tv_begin.tv_usec); #endif for(i=0L; i<T1; i++) for(j=0L; j<T2; j++) for(k=0L; k<T3; k++) ; #ifdef TEST_Ts
gettimeofday( &tv_end, NULL); printf("End time: %d sec : %d microsec\n", tv_end.tv_sec, tv_end.tv_usec);
delta_sec = tv_end.tv_sec - tv_begin.tv_sec;
delta_usec = tv_end.tv_usec - tv_begin.tv_usec;
if(delta_usec < 0) { delta_sec--; delta_usec += 1000000L; } printf("Diferenta timer: %d sec : %d microsec\n", delta_sec, delta_usec); #endif } #endif
/*Al doilea program aferent blocarii semnalelor Blocarea semnalelor pentru handlere: în acest exemplu semnalul SIGTSTP este întrerupt de semnalele SIGINT si SIGQUIT*/
#include <stdio.h> #include <signal.h>
#include "my_sleep.h" //se foloseste fisierul header
/* handler-ul propriu pentru semnalele SIGINT */ void catch_intr() { /* recoruperea semnalului */ signal(SIGINT, catch_intr); /* actiuni dorite de utilizator */ printf("Executie handler de semnal SIGINT.\n" ); my_sleep1sec(); printf("Sfirsit handler SIGINT.\n" ); */ }
/*Al treilea program aferent blocarii semnalelor Verificarea blocarii anumitor semnale*/
#include <stdio.h> #include <signal.h>
void main() { sigset_t base_mask, waiting_mask; int i;
printf("Inceput program. %s%s%s\n", "Puteti oricind tasta ^C sau ^Z pentru a termina/stopa programul, ", "totusi acest lucru se va intimpla doar dupa 10 sec. ", "Iar daca nu tastati ^C si nici ^Z, se va sfirsi dupa 20 sec." );
sigemptyset(&base_mask); sigaddset(&base_mask, SIGINT); sigaddset(&base_mask, SIGTSTP);
/* se blocheaza semnalele ^C si ^Z generate de utilizator */ sigprocmask(SIG_SETMASK, &base_mask, NULL);
/* un interval de 10 sec. */ for(i=0; i<10; i++) { sleep(1); printf("Time: %d seconds\n", i+1); }
/* se verifica daca exista semnale SIGINT sau SIGTSTP în asteptare */ sigpending(&waiting_mask); if( sigismember(&waiting_mask, SIGINT) ) { printf("Userul a incercat sa termine procesul in primele 10 sec.\n" ); } if( sigismember(&waiting_mask, SIGTSTP) ) { printf("Userul a incercat sa stopeze procesul in primele 10 sec.\n" ); }
/* se deblocheaza semnalele ^C si ^Z generate de utilizator */ sigprocmask(SIG_UNBLOCK, &base_mask, NULL);
/* un alt interval de 10 sec. */ for(i=0; i<10; i++) { sleep(1); printf("Time: %d seconds\n", i+1); }
printf("Sfirsit program dupa 20 sec.\n" ); }
|
|