I Inter-Prozess-Kommunikation in Linux lerne, mit kill() Signale senden Kind process.Here zu schlafen ist mein Programm:Warum wird mein Signalhandler zweimal ausgeführt?
8 void func(void);
9 int main(void){
10 int i, j;
11 pid_t status, retpid;
12 signal(17,func);
13 if(i = fork()){
14 printf("Parent:signal 17 will be sent to child!\n");
15 kill(i, 17);
16 wait(0);
17 printf("child process terminated\n");
18 }
19 else{
20 sleep(10);
21 printf("Child: A signal from my parent is received!\n");
22 exit(0);
23 }
24 }
25 void func(void)
26 {
27 printf("the signal has been sent!\n");
28 }
mit gcc kompiliert, das Programm erzeugt anormales Ergebnis, bei dem func () zweimal ausgeführt:
./test4.out
Parent:signal 17 will be sent to child!
the signal has been sent!
Child: A signal from my parent is received!
the signal has been sent!
child process terminated
I das Ergebnis analysiert, und dann die beiden folgenden Zeilen gelöscht:
16 wait(0);
17 printf("child process terminated\n");
und das Ergebnis b wurde normal, mit func() nur einmal aufgerufen. Es scheint, dass der Schuldige die wait() - Funktion ist, aber warum sollte er jemals einen Signal-Handler aufrufen?
** Vielleicht **, wenn der Elternprozess geschlossen wird, wartet er auf ein KILL-Signal vom Prozessmesser ...? Wenn ein Prozess beendet ist, stirbt er nicht wirklich. Es bleibt, bis der "Rapper" (entweder der Besitzer oder der Systemprozess, der für das Ernten von Zombie-Prozessen zuständig ist) fertig ist ... Es könnte der Sensenmann sein, der signalisiert, dass es getan ist. – Myst
'printf' ist keine signalsichere Funktion und sollte nicht in einem Signalhandler aufgerufen werden. Die mögliche Erklärung ist, dass es Undefined Behavior verursacht (z. B. den Stout-Puffer zweimal löschen - einmal im Signal-Handler und einmal, wenn der Prozess beendet wird). – kaylum
bitte Text eingeben, nicht mit vorangestellten Zeilennummern. Wir können den geposteten Code nicht einfach in unsere Editoren einfügen und einfügen, ohne viel Zeile für Zeile bearbeiten zu müssen. Verwenden Sie keine Tabs zum Einrücken, da für jedes Textverarbeitungsprogramm/Editor die Tabstopps/Tabulatoren für die einzelnen Einstellungen festgelegt sind. Auch nach dem Beheben des Zeilennummernproblems kompiliert der gebuchte Code nicht. Es scheint zu fehlen die benötigten '# include' Anweisungen – user3629249