如何使Python程序运行另一个Python程序,就像从单独的SSH终端运行一样?

4
在运行着Jessie系统的树莓派2上,我有两个显示屏,一个是默认的HDMI显示屏,另一个是LCD触摸屏(需要使用os.environ来设置一些与SDL相关的变量)。我有两个pygame程序,lcd.py和hdmi.py。当我从不同的SSH终端中运行它们时,它们能够良好地共存。lcd.py显示几个按钮,hdmi.py则在连接的HDMI显示屏上展示幻灯片。
如果我在两个SSH终端中分别以“pi”用户身份(使用sudo python PROGRAM)运行它们,则lcd.py会显示到LCD上,而hdmi.py会在HDMI屏幕上显示幻灯片。
然而,我无法想出如何使lcd.py调用hdmi.py程序作为一个完全独立的进程(因此它有自己的环境变量,并且可以独立于驱动LCD显示的父进程驱动HDMI显示)。 lcd.py程序有一个按钮,当触摸它时,会调用startSlideShow()例程。然而,在lcd.py的startSlideShow()函数中尝试启动hdmi.py的各种方法都失败了:
def startSlideShow():
   # when running in SSH the correct command is 
   #     sudo python /home/pi/Desktop/code/hdmi.py
   # or  sudo /usr/bin/python /home/pi/Desktop/code/hdmi.py
   # tried various ways of invoking hdmi.py via
   # os.fork(), os.spawnl(), subprocess.Popen()
   WHAT GOES HERE?

不需要进行持续的进程间通信。 除了当lcd.py程序需要“启动”hdmi.py程序时,它们不需要通信,对我来说,终止lcd是否终止hdmi.py程序并不重要。

在startSlideShow()中尝试但不起作用的事情:

cmd = "sudo /usr/bin/python /home/pi/Desktop/code/hdmi.py"
pid = os.spawnl(os.P_NOWAIT, cmd)
# lcd.py keeps running, but creates a zombie process [python]<defunct>  instead of running hdmi.py

并且
cmd = "sudo /usr/bin/python /home/pi/Desktop/code/hdmi.py"
pid = os.spawnl(os.P_DETACH, cmd)
# lcd.py exits with error AttributeError: 'module' object has no attribute 'P_DETACH'

And

cmd = "sudo /usr/bin/python /home/pi/Desktop/code/hdmi.py"
pid = os.spawnl(os.P_WAIT, cmd)
# no error message, returns a pid of 127, but does nothing, and no such process exists when I run `ps aux` in another SSH terminal

并且
cmd = ["/usr/bin/python", "/home/pi/Desktop/code/hdmi.py" ]
pid = subprocess.Popen(cmd, stdout=subprocess.PIPE).pid # call subprocess
# runs the hdmi.py program, but output goes to LCD not HDMI 
# (the 2 programs alternately take over the same screen) 

And

cmd = ["/usr/bin/python", "/home/pi/Desktop/code/hdmi.py" ]
pid = subprocess.Popen(cmd).pid
# as above, both programs run on same display, which flashes between the two programs

And

pid = os.spawnlp(os.P_NOWAIT, "/usr/bin/python",  "/home/pi/Desktop/code/hdmi.py")
# invokes python interpreter, get >>> on SSH terminal

And

pid = os.spawnlp(os.P_NOWAIT, "/usr/bin/python /home/pi/Desktop/code/hdmi.py")
# creates zombie process [python] <defunct>

1
你知道两者之间共享了哪些不想要的内容吗?你提到了环境变量,但子进程确实有它们自己的环境变量集,只是它们被初始化为与父进程相同的值。如果问题在于两者需要不同的DISPLAY值,则popen将允许您使用popen构造函数的env参数指定替代值。您也可以尝试将子进程作为守护进程生成:https://dev59.com/eW025IYBdhLWcg3w1JiG - Pace
使用 env= 起作用了,谢谢。如果你想把它作为答案添加,我会接受的。 - jpw
关于不同 $DISPLAY 的问题如何与“仿佛是从单独的SSH终端运行”相关(前者涉及环境变量(传递 env 参数),后者涉及 preexec_fn=os.setsid(以及可能是通常用于守护进程的其他方面))。 - jfs
1个回答

2
为了给子进程提供与父进程不同的环境变量值,您可以使用POpen构造函数的env参数并提供所需的值。例如,这应该允许您提供不同的DISPLAY值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接