我在Python服务器脚本中运行两个子进程。子流程的目的是从我的Raspberry Pi中流式传输视频。
我的问题是当另一个命令发送到服务器时如何终止子进程。我目前正在使用Popen()来启动子进程。
这是我的服务器收到命令“startStream”时的代码。我使用Twisted库作为服务器协议。
class Echo(Protocol):
def connectionMade(self):
#self.transport.write("""connected""")
self.factory.clients.append(self)
print "clients are ", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
def dataReceived(self, data):
print "data is ", data
if data == "startStream":
p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True)
pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True)
我想要的是这样的。
if data == "startStream":
p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True)
pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True)
elif data == "stopStream":
os.kill(p.pid)
os.kill(pn.pid)
非常感谢!
答案 0 :(得分:1)
你在这里缺少一些上下文,但基本上服务器会做类似的事情:
while True:
data = wait_for_request()
if data == 'startStream':
p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True)
pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True)
elif data == 'stopStream':
p.terminate()
pn.terminate()
关键部分是名称p
和pn
存在于同一范围内,因此可以在不使用任何类型的全局状态的情况下访问它们。如果您的代码结构不同,则需要对其进行概述。
由于data_received
在每次调用时都有自己的作用域,因此需要以不同的方式传递对Popen对象的引用。
幸运的是,您可以在类实例中保留引用。
def dataReceived(self, data):
if data=='startStream':
self.p = subprocess.Popen() # ...
self.pn = subprocess.Popen() # ...
elif data=='stopStream':
self.p.terminate()
self.pn.terminate()
Popen.terminate
可以从Python 2.6获得,应该可以正常工作 - 我不确定问题的评论是什么问题。