Alarm() Frage ablauf



  • Hallo,

    kann mir jemand den ablauf dieses programmes erklären?

    genauer gesagt den fett markierten part:

    [code]
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <iostream.h>
    #include <sys/errno.h>
    #include <signal.h>
    
    void zeitberechnung(int);
    void anhalten(int);
    void toete(int);
    
    int exitstat;
    int anfZeit;
    int waitResult;
    int endZeit;
    int laufzeit;
    int pidson;
    int watchdog;
    
    int main (int argc, char *argv[]){
    
    if (argc==1)
    {
       cout << "Sie muessen einen Programmnamen angeben \n"<< endl; 
       exit(1);
    }
    
    	/*Prozess erzeugen*/
    	switch(pidson=fork())
    	{
       	case -1:
          	perror(argv[0]);
          	exitstat=2;
          	break;
    
       	case 0: /*Sohnprozess*/
          	cout << "Das Programm " << argv[1] << " wird gestartet " << endl;
          	execvp(argv[1], &argv[1]);
          	perror(argv[0]);
          	exitstat=3;
          	break;
    
       	default: /*Vaterprozess*/
    
    	switch(watchdog = fork()){
    
    	case -1:
    		perror(argv[0]);
          		exitstat=2;
          		break;
    
    	case 0:
    		while(true){
    
    		[b]signal (SIGALRM, anhalten);
    		alarm(6);
    		pause();
    
    		signal (SIGALRM, toete);
    		alarm(3);
    
    		getchar();
    		alarm(0);
    		kill(pidson, SIGCONT);[/b]
    		}		
    
    		break;
    
    	default:
    
          	anfZeit=time(NULL);
          	wait(&waitResult);
          	endZeit=time(NULL);
          	laufzeit=endZeit-anfZeit;
    
    	  cout << "Die PID des Vaters ist: " << getpid() << endl;
    	  cout << "Die PID des Sohns war : " << pidson << endl;
    	  zeitberechnung(laufzeit);
    	  if(waitResult==0)
    	  	{
    	  cout << "\nProgramm wurde mit exit=" << waitResult << " beendet!\n";
    		}
    	  if(waitResult<=255 && waitResult != 0)
    			 	{
    	  cout << "\nProgramm  wurde mit Signalnummer " << waitResult <<" beendet!\n";
    				}
    	  if(waitResult>255)
    			 	{
    	  cout << "\nProgramm wurde mit exit=" << waitResult/256 <<" beendet!\n";
    				}
          exitstat=0;
          break;
    }
    }
    
    kill(watchdog, SIGKILL);
    exit(exitstat);
    }
    
    void zeitberechnung(int zeit)
    {
    	int hour=0;
        	int min=0; 
    	int sec=0;
    	hour=zeit/3600;
    	min=(zeit-(hour*3600))/60;
    	sec=(zeit-(hour*3600))-(min*60);
    	cout << "\nLaufzeit war ";
    	cout << hour << " Stunden ";
    	cout << min <<"  Minuten und ";
    	cout << sec <<"  Sekunden.\n";
    }
    
    void anhalten(int sig_nr){
    
    	kill (pidson, SIGSTOP);
    	cout << " 3 sec zum Enter drücken " << endl;
    
    }
    
    void toete(int sig_nr){
    
    	cout << "Kein ENter gedrückt tschüss" << endl;
    	kill (pidson, SIGKILL);
    }
    

    [/code]

    so wie ich das vermute wird ist signal() dazu da um signale an prozess zu senden hierbei benutzen wir SIGALRM welches ich nicht verstehe

    desweiteren verstehe ich nicht die darauffolgende alarm() und pause()

    wir programmieren sonst java

    Das programm sol zur signal erläutung beitragen

    THX



  • mit alarm kann man einen timeout auf eine bestimmte anzahl an sekunden stellen. sobald diese zeit abgelaufen ist, bekommt das programm ein SIGALRM zugestellt und der passende signal handler wird aufgerufen.

    in deinem beispiel wird in den ersten beiden fällen jeweils mit signal ein handler für SIGALRM installiert. dann wird der timer mit alarm gestartet. im ersten fall wird mit pause auf das eintreffen von SIGALRM gewartet (das programm blockiert dort). beim zweiten mal wird nicht per pause gewartet sondern auf eine eingabe des users. diese eingabe kann vor dem signal passieren, sodass mit alarm(0) der timer wieder abgeschaltet wird. sollte der user nicht innerhalb von drei sekunden etwas eingeben, wird signal doch verschickt und der handler "toete" ausgeführt. wie genau getchar mit einem signal umgeht, weiß ich nicht. ich denke aber, dass es abbrechen wird und errno auf EINTR gesetzt wird. fgetc tut zumindest das. das kill sendet dann an einen kindprozess das signal SIGCONT.


Anmelden zum Antworten