2013-12-13 180 views
0

我試圖在下面的函數中打開第二個python腳本的子進程。它似乎打開過程很好,但是當我嘗試結束該過程時,父進程終止並且子進程仍然存在。有關爲什麼會發生這種情況的任何建議?.kill()在python子進程中殺死父進程而不是子進程

def thermostat(input): 
global ThermostatRunning 
global proc 
print("Thermostat Function input: %s" % input) 
if input == 'stop' and ThermostatRunning == 1: 
    print("test") 
    proc.kill() 
    print proc.poll() 
    dev2(0) #ensure heater is off 
    return('Thermostat turned off') 
elif input=='stop' and ThermostatRunning == 0: 
    status = "Thermostat already stopped" 
    print(status) 
    return(status) 
if input.isdigit() == 0: 
     return("Thermostat input is not a number or -stop-") 
if ThermostatRunning == 1: 
    print("test2") 
    proc.kill() 
print("test3") 
proc = subprocess.Popen('python thermostat.py -t %s' % input, shell=True)#, preexec_fn=os.setsid) 
ThermostatRunning = 1 
#for line in proc.stdout.readlines(): 
    #print (line) 
status = "Thermostat started with set temperature: %s" % input 
print(status) 
return(status) 

唯一的其他問題,可能是相關的是,這是一個燒瓶腳本。我不確定這是否會改變任何事情。

+0

你是如何準確地調用這個函數(從一個單獨的模塊,類文件,等等?)。總的來說,我建議把它放在一個類中,儘量避免使用全局變量,但我不確定這是否與您遇到的問題有關。 –

+0

我從同一個文件中的另一個函數調用。我對Python非常陌生,並且沒有很多類的經驗。 – brett

+0

python thermostat.py是其他進程的佔位符嗎?否則,爲什麼你需要'shell = True'? 'Popen([sys.executable或'python','-mthermostat','-t',input])'應該在沒有shell的情況下工作。你需要它是一個單獨的過程?你有沒有試過從溫控器導入some_function; some_function(輸入)'? – jfs

回答

0

當你使用shell = True創建子進程時,你實際上產生了一個產生另一個子進程的進程,所以當你調用proc.kill()時,你只會殺死父進程。你想讓你的子進程成爲進程組的領導者,這樣你就可以一次性殺掉它們。

取消註釋器一起調用setsid並殺死整個進程組,像這樣:

os.killpg(proc.pid, signal.SIGTERM) 
+0

是的,這是我試圖讓它工作的事情之一,但這似乎殺死了兩者。是否有可能使用這種方法只殺死子進程? 謝謝! – brett

+0

@brett:你忘了取消'setsid'的註釋嗎? – jfs

+0

@ J.F.Sebastian不,這是沒有註釋的。 – brett