2016-05-06 9 views
0

Wenn ein Programm einen INT-Befehl ausgibt, übernimmt das OS die Anforderung und behandelt sie. Ich verstehe das Gegenteil davon nicht, wie die Steuerung vom Betriebssystem in Prozesse übertragen wird, wenn Signale gesendet und bearbeitet werden. Okay, das Betriebssystem sendet das Signal an den Prozess. Wie genau wird es überhaupt gemacht? Wenn es um Pakete und Sockets geht, kann ich den Ablauf der Kontrolle verstehen. Ich gehe davon aus, dass das Sendesignalbit im Wesentlichen etwas in ein Register schreibt und den Programmzähler auf einen bestimmten Punkt einstellt und den Maschinenzustand zurück in den geschützten Modus versetzt. Ich lese ein wenig darüber, wie man die Fehlerbehandler mit dem Betriebssystem und solchen Dingen registriert. Und das ergab einen Sinn. Wenn ein Fehler auftritt, bitten Sie das Betriebssystem, den Programmzähler an einen Punkt im Benutzerbereichscode zu verschieben, der die Fehlerbehandlungsroutine darstellt. Aber eine Menge davon ist immer noch sehr verschwommen für mich. Welche Rolle spielt das Signal? Wie weiß der Prozess, dass das Signal angekommen ist?Wie gehen Prozesse mit Signalen um?

Kann jemand den Steuerfluss während des Sendens und Handhabens von Signalen erklären?

+0

wird nützlich sein, um zu lesen, wie der Linux-Scheduler arbeitet – red0ct

+0

Mögliche Duplikat [Wie asynchrone Signal-Handler auf Linux ausgeführt werden?] (Http://stackoverflow.com/questions/6949025/how-are-asynchronous -signal-handler-executed-on-linux – shodanex

Antwort

1

Das ist völlig nicht wie es funktioniert.

int 0x80 (und dergleichen) ist eine alte Methode und unbenutzt auf amd64 (es gibt eine dedizierte Anweisung 'syscall'). Dies hat jedoch keine Beziehung zu dem Problem.

Kurz gesagt, Threads durchlaufen Kernel < -> Userspace Grenze die ganze Zeit (syscalls, Ausnahmen (z. B. Seitenfehler) oder einfach durch geplant werden). Wenn der Thread in den Benutzerbereich zurückkehrt, prüft er einfach, ob irgendwelche Signale ausstehen.

Bei der sogenannten Signal Delivery handelt es sich einfach darum, eine Information irgendwo zu speichern, an der ein Signal ansteht und den Ziel-Thread aufzuwecken, um damit umzugehen. Der aufgewachte Thread kehrt zur Userspace-Grenze zurück, wo er die genannten Sachen ausführt.

Der eigentliche Mechanismus, der zum Aufruf eines Signal-Handlers und anschließendem Bereinigen benötigt wird, ist komplizierter und ich kann nur empfehlen, ein Buch über Betriebssysteme zu bekommen.

1

Welche Rolle spielt das Signal?

Sie wissen zu lassen, dass etwas auf dem System mit genügend Berechtigungen Sie ein Signal gesendet hat, hatte jedes Signal eine disposition dh eine Standardaktion, dass Ihr Prozess etwas also in vielen Fällen tun, es sei denn gefangen beenden oder eine generieren Core Dump usw.

Okay, das OS sendet das Signal an den Prozess. Wie genau wird es überhaupt gemacht?

Das Betriebssystem kann tun, was es will. Ich könnte beliebige Funktionen in Ihrem Programm aufrufen, wenn es gewünscht wird, im Falle eines Signals prüft es, ob Sie einen Signal-Handler haben, und wenn ja, ruft er das mit der Signalnummer an. Wenn nicht, tut es was auch immer der Standard für dieses System ist.

Woher weiß der Prozess, dass das Signal angekommen ist, um behandelt zu werden?

Sie können einen Handler festlegen, der Sie informiert, wann er ankommt. Wenn Sie keinen Handler festlegen, wird eine Standardaktion ausgeführt.

Im folgenden Code kompilieren Sie es und führen Sie es dann verwenden Sie CTRL-c, um es zu beenden oder verwenden Sie Kill, um es verschiedene Signalnummern zu senden. Dies zeigt Fangsignale.

CAVEAT. Der folgende Code wurde auf Mac und Linux ausgeführt und macht eine Menge Annahmen über die ganzzahligen Werte, wenn die Signale, es ist sicherlich nicht portabel, es ist hier als ein Beispiel, wie Sie Signal verwenden können, um nur eine signal_handler-Funktion einzurichten.

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <time.h> 
#include <unistd.h> 

extern char *taunts[]; 
int taunt(); 

void sig_handler(int signo) { 
    switch(signo) { 
    case SIGHUP: printf("\t%s %d\n", taunts[taunt()], SIGHUP);break; 
    case SIGINT: printf("\t%s %d\n", taunts[taunt()], SIGINT);break; 
    case SIGQUIT: printf("\t%s %d\n", taunts[taunt()], SIGQUIT);break; 
    case SIGILL: printf("\t%s %d\n", taunts[taunt()], SIGILL);break; 
    case SIGTRAP: printf("\t%s %d\n", taunts[taunt()], SIGTRAP);break; 
    case SIGABRT: printf("\t%s %d\n", taunts[taunt()], SIGABRT);break; 
    case SIGFPE: printf("\t%s %d\n", taunts[taunt()], SIGFPE);break; 
    case SIGKILL: printf("\t%s %d\n", taunts[taunt()], SIGKILL);break; 
    case SIGBUS: printf("\t%s %d\n", taunts[taunt()], SIGBUS);break; 
    case SIGSEGV: printf("\t%s %d\n", taunts[taunt()], SIGSEGV);break; 
    case SIGSYS: printf("\t%s %d\n", taunts[taunt()], SIGSYS);break; 
    case SIGPIPE: printf("\t%s %d\n", taunts[taunt()], SIGPIPE);break; 
    case SIGALRM: printf("\t%s %d\n", taunts[taunt()], SIGALRM);break; 
    case SIGTERM: printf("\t%s %d\n", taunts[taunt()], SIGTERM);break; 
    default: printf("\tMerde\n"); 
    } 
#ifdef __linux__ 
    if (signal(signo, sig_handler) == SIG_ERR) { 
    printf("Merde: %d\n", signo); 
    } 
#endif 
} 

int main(void) { 
    srand(time(NULL)); 
    int i = 0; 
    for(i = 0; i < 15; i ++) { 
    if (signal(i, sig_handler) == SIG_ERR) { 
     printf("Merde: %d\n", i); 
    } 
    } 
    while(1) { 
    sleep(10); 
    } 
    return 0; 
} 

int taunt() { 
    return rand() % 12; 
} 

char *taunts[13] = { 
"\n No, now go away or I shall taunt you a second time! With youri\n rubbish signal... ", 
"\n You don't frighten us, English pig dogs with your daft signal... ", 
"\n Go and boil your bottoms, you sons of a silly person and your\n \ 
    nincompoop signal... ", 
"\n I blow my nose at you, so-called \"Arthur King,\" you and all\n \ 
    your silly English K-nig-hts. With your silly signal... ", 
"\n I'm French. Why do you think I have this outrageous accent, you\n \ 
    silly king? With your silly signal... ", 
"\n Mind your own business With your ludicrous signal... ", 
"\n You don't frighten us with your silly knees-bent running around\n \ 
    advancing behavior! With your silly signal... ", 
"\n How you English say, I one more time-a unclog my nose in your\n" 
    " direction, sons of a window-dresser! With your weak signal... ", 
"\n No chance, English bedwetting types. With your outrageous signal... ", 
"\n Yes, depart a lot at this time and cut the approaching any more\n \ 
    or we fire arrows at the tops of your heads and make castanets\n \ 
    out of your testiclesi already! With your stupido signal.." 
"\n And now remain gone illegitimate faced buggerfolk! and your farty\n signal... ", 
"\n And, if you think you got nasty taunting this time, you ain't\n heard nothing yet! I signal in your general direction... ", 
"\n Daffy English kniggets! Thpppt!... ", 
};