2017-01-19 2 views
2

Ich versuchte mit os.kill, aber es scheint nicht zu funktionieren.Wie sende ich ein Signal vom Subprozess zum übergeordneten Prozess?

import signal 
import os 
from time import sleep 


def isr(signum, frame): 
    print "Hey, I'm the ISR!" 

signal.signal(signal.SIGALRM, isr) 

pid = os.fork() 
if pid == 0: 
    def sisr(signum, frame):   
     os.kill(os.getppid(), signal.SIGALRM) 

    signal.signal(signal.SIGVTALRM, sisr) 
    signal.setitimer(signal.ITIMER_VIRTUAL, 1, 1) 

    while True: 
     print "2" 
else: 
    sleep(2) 

Antwort

1

Ihr Handler sisr wird nie ausgeführt.

signal.setitimer(signal.ITIMER_VIRTUAL, 1, 1) 

Diese Linie stellt einen virtuellen Zeitgeber, der nach Dokumentation, „Dekrementiert Intervalltimer nur dann, wenn der Prozess ausgeführt wird, und liefert SIGVTALRM nach Ablauf“.

Die Sache ist, Ihr Prozess wird fast nie ausgeführt. Die Ausdrucke benötigen fast keine Zeit in Ihrem Prozess, die ganze Arbeit wird vom Kernel erledigt, der die Ausgabe an Ihre Konsolenanwendung (xterm, konsole, ...) liefert und die Anwendung den Bildschirm neu streicht. Der untergeordnete Prozess ist inaktiv und der Timer wird nicht ausgeführt.

ändern es mit einem echten Timer, es funktioniert :)

import signal 
import os 
from time import sleep 


def isr(signum, frame): 
    print "Hey, I'm the ISR!" 

signal.signal(signal.SIGALRM, isr) 

pid = os.fork() 
if pid == 0: 
    def sisr(signum, frame):   
     print "Child running sisr" 
     os.kill(os.getppid(), signal.SIGALRM) 

    signal.signal(signal.SIGALRM, sisr) 
    signal.setitimer(signal.ITIMER_REAL, 1, 1) 

    while True: 
     print "2" 
     sleep(1) 
else: 
    sleep(10) 
    print "Parent quitting" 

Ausgang:

[email protected]:~/temp$ python test.py 
2 
Child running sisr  
2 
Hey, I'm the ISR! 
Parent quitting 
[email protected]:~/temp$ Child running sisr 

Traceback (most recent call last): 
    File "test.py", line 22, in <module> 
    sleep(1) 
    File "test.py", line 15, in sisr 
    os.kill(os.getppid(), signal.SIGALRM) 
OSError: [Errno 1] Operation not permitted 

Hinweis: das Kind stürzt die Sekunden Zeit sisr läuft, weil dann die Elternteil wurde verlassen, so os.getppid() Rückkehr 0 und Senden eines Signals an Prozess 0 ist verboten.

+0

Ich wusste nicht, dass "print" überhaupt keine CPU-Zeit verbraucht! Anstatt zu drucken, habe ich jetzt etwas Rechnen gemacht. Aber vielen Dank! –

+1

Es tut, aber die Menge, die es verwendet, ist vernachlässigbar vor der Zeit, die der Text durch den Kernel an den Konsolenemulator verbracht hat, der dann die Schriftart in dem Fenster rendern muss, der wiederum den Fenstermanager anweist, die Aktualisierung an zu senden der Videotreiber oder was auch immer er damit macht. – spectras

+0

Wenn also der Timer läuft (virtuell), wird alles, was im Kernel passiert, nicht berücksichtigt, oder? –

Verwandte Themen