我写了一个函数fun0
,它调用:
p1
,fun1
,fun2
的函数p2
。两个进程p1
和p2
是外部文件。函数fun0
的代码为:
def fun0():
# call the 1. process
p1 = subprocess.Popen(["python", "script1.py"])
try:
p1.wait()
except KeyboardInterrupt:
try:
p1.terminate()
except OSError:
pass
p1.wait()
# call the 1. function
fun1()
# loop 3 times
for i in range(1, 3, 1):
# call the 2. function
fun2()
def fun2():
# call 2. process
p2 = subprocess.Popen(["python", "script2.py"])
try:
p2.wait()
except KeyboardInterrupt:
try:
p2.terminate()
except OSError:
pass
p2.wait()
script_2.py使用线程来同时运行两个函数。代码如下:
import threading
def Ref():
read ref. value
return ref. value
def Read():
while read_interval <= some_time:
read value
yield value
def Add():
while delta > error:
while delta > limit :
while True:
value = next(Read())
delta = change delta
check conditions
while True:
value = next(Read())
delta = change delta
check conditions
return result
if __name__ == '__main__':
t0 = threading.Thread(target = Ref)
t0.start()
t0.join()
readTime = datetime.now()
t1 = threading.Thread(target = Read)
t2 = threading.Thread(target = Add)
t1.start()
t2.start()
t1.join()
t2.join()
我想从外部(即从另一个函数)停止执行函数fun0()
。当停止发生时,我还希望函数fun1
,fun2
并处理p1
,p2
以停止并可能从中检索数据。我不知道这是一种优雅,干净和Pythonic的方式。我正在考虑:
我已经阅读了此post 28906558中有关使用multiprocessing
停止该功能的方法,但我想听听更多意见,谢谢。
答案 0 :(得分:0)
出于这个问题的目的,我对函数fun1
以及子流程p1
和p2
使用了简单的倒计时。然后,我开始尝试将该功能用作流程解决方案。主程序的代码是:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
#An example of how to terminate the execution of a function
#which calls a process using an external trigger.
import time
import subprocess
from multiprocessing import Process, Queue
def fun0():
# start process1
p1 = subprocess.Popen(["python", "eg_script1_countdown1.py"])
p1_PID = p1.pid
print "p1_PID:", p1_PID
try:
p1.wait()
except KeyboardInterrupt:
try:
p1.terminate()
except OSError:
pass
p1.wait()
# call function1
fun1()
# loop 3 times
for i in range(1, 3, 1):
# call fun2
print "call function 2, loop n.", i
fun2()
def fun1():
for i in range(5,0,-1):
print "fun1 > take five in", i
time.sleep(1)
def fun2():
# start process2
p2 = subprocess.Popen(["python", "eg_script2_countdown2.py"])
p2_PID = p2.pid
print "p2_PID:", p2_PID
try:
p2.wait()
except KeyboardInterrupt:
try:
p2.terminate()
except OSError:
pass
p2.wait()
if __name__ == '__main__':
pMain = Process(target=fun0)
pMain_PID = pMain.pid
print "pMain_PID:", pMain_PID
pMain.start()
time.sleep(20)
pMain.terminate()
第一个被调用文件的代码为:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
#eg_script1_countdown.py
import time
for i in range(10,0,-1):
print "script1.py > have a beer in", i
time.sleep(1)
以及第二个文件:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
#eg_script2_countdown.py
import time
for i in range(10,0,-1):
print "script2.py > give love in", i
time.sleep(1)
我正在更改time.sleep(20)
中的行__name__ == '__main__'
,以查看内部终端pMain.terminate()
如何影响结果。我发现:
p1
运行时被触发时,它不会终止它,fun1()
运行时被触发时,它会终止功能,p2
正在运行时被触发时,它不会终止该过程,但会在下一个循环中终止fun2()
。如何在运行时终止子进程p1
和p2
?
答案 1 :(得分:0)
我确实按照建议in this thread在pMain.daemon = True
之前使用pMain.start()
修改了主程序的代码,但是进程p1
仍然在后台运行,甚至退出了。
import os
import time
import signal
import subprocess
from subprocess import Popen, PIPE
import multiprocessing
from datetime import datetime
def fun0():
p1 = subprocess.Popen(["python", "eg_script1_countdown1.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
#p1 = subprocess.Popen(["python", "eg_script1_countdown1.py"])
global p1_pid
p1_pid = p1.pid
print "p1_pid:", p1_pid
try:
p1.wait()
except KeyboardInterrupt:
try:
p1.terminate()
except OSError:
pass
p1.wait()
# call fun1
fun1()
# loop 3 times
for i in range(3):
# call fun2
print "call fun2, loop n.", i
with open('/home/parovelb/Desktop/Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' for loop n. ' + str(i) + "\n")
fun2()
def fun1():
for i in range(5,0,-1):
print "fun1 > take five in", i
with open('/home/parovelb/Desktop/Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' fun1 ' + str(i) + "\n")
time.sleep(1)
def fun2():
# start process2
p2 = subprocess.Popen(["python", "eg_script2_countdown2.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
#p2 = subprocess.Popen(["python", "eg_script2_countdown2.py"])
global p2_pid
p2_pid = p2.pid
try:
p2.wait()
except KeyboardInterrupt:
try:
p2.terminate()
except OSError:
pass
p2.wait()
if __name__ == '__main__':
# original code
pMain = multiprocessing.Process(target=fun0)
pMain.daemon = True
pMain.start()
time.sleep(10)
pMain.terminate()
exit()
答案 2 :(得分:0)
在帖子delegate-sigint-signal...和delegate-signal-handling...中提出建议的解决方案之后,我修改了主程序的代码:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
"""
This is an example of a simple terminaton of a subprocess with a ctrl+c.
"""
import time
import signal
import subprocess
def signal_handler(signal, frame):
print "outer signal handler"
exit(2)
def fun1():
for i in range(5,0,-1):
print "fun1 > take five in", i
time.sleep(1)
def execute():
# call the process first
proc = subprocess.Popen("python eg_test.py",shell=True)
try:
proc.wait()
except KeyboardInterrupt:
try:
proc.terminate()
except OSError:
pass
# call the function second
fun1()
def main():
signal.signal(signal.SIGINT, signal_handler)
execute()
time.sleep(5)
proc.send_signal(signal.SIGINT)
main()
我还只是为了测试运行而修改了一个外部脚本:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
"""
This is an example of a simple for loop countdown run a subprocess and
terminated with ctrl+c.
"""
import time
import signal
from datetime import datetime
def signal_handler(signal, frame):
print "exiting: inner function"
exit(2)
def main():
#define the signal handler
signal.signal(signal.SIGINT, signal_handler)
# simple for loop countdown
for i in range(20,0,-1):
print "test.py > countdown", i
time.sleep(1)
main()
在过程中按ctrl + c
时(正在运行外部脚本),它将终止它,然后继续执行fun1()
。问题仍然存在:如何从另一个函数终止execute()
函数?
答案 3 :(得分:0)
经过反复试验后,我得到了代码。我感觉还有很多改进的空间。主要脚本的代码:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
"""
This is an example of a simple terminaton of a subprocess with a ctrl+c.
"""
import os
import time
import signal
import subprocess
import multiprocessing
from datetime import datetime
p1_pid = 0
proc_pid = 0
def signal_handler(signal, frame):
print " main signal handler "
# write to log
with open('.../Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' exiting: main function ' + "\n")
exit(2)
def f1():
for i in range(5,0,-1):
print "f1 > main function", i
# write to log
with open('/home/parovelb/Desktop/Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' main function ' + str(i) + "\n")
time.sleep(1)
def execute():
# call the function second
f1()
# call the process first
global p1, p1_pid
p1 = subprocess.Popen(["python", "eg_test.py"], shell=False)
p1_pid = p1.pid
print "p1_pid", p1_pid
try:
p1.wait()
except KeyboardInterrupt:
try:
p1.terminate()
except OSError:
pass
def kill_them_all():
time.sleep(10)
print "p1_pid", p1_pid
os.kill(p1_pid,signal.SIGINT)
os.kill(proc_pid,signal.SIGINT)
def main():
# define signal handler
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
global proc, proc_pid
proc = multiprocessing.Process(target=execute)
proc_pid = proc.pid
print "proc_pid", proc_pid
proc_end = multiprocessing.Process(target=kill_them_all)
proc.start()
proc_end.start()
proc.join()
proc_end.join()
main()
外部脚本的代码:
#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-
import time
import signal
from datetime import datetime
def signal_handler(signal, frame):
print " external signal handler "
with open('.../Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' exiting: external function ' + "\n")
exit(2)
def main():
#define the signal handler
signal.signal(signal.SIGINT, signal_handler)
# simple for loop countdown
for i in range(20,0,-1):
print "eg_test.py > external file > main function", i
with open('.../Python2.7/log.txt', 'a') as log:
log.write(str(datetime.now()) + ' external function ' + str(i) + "\n")
time.sleep(1)
main()