4

On a Raspberry Pi 2 running Jessie I have two displays, a (default) HDMI display, and an LCD touch screen (which requires a couple of SDL-related variables to be set using os.environ).

I have two pygame programs, lcd.py and hdmi.py which, when run from separate SSH terminals, coexist nicely, the lcd.py dsiplays a few buttons, the hdmi.py displays a slideshow on the attached HDMI display.

If I run them separately in two SSH terminals (as the 'pi' user, using sudo python PROGRAM), the lcd.py displays to the LCD and the hdmi.py displays a slideshow to the HDMI screen.

However, I cannot figure out how to have lcd.py invoke the hdmi.py program as a completely independent process (so it has its own env variables, and can drive the HDMI display independently of the parent process driving the LCD display).

The lcd.py program has a button that when touched invokes the routine startSlideShow()

However, the various things I tried in lcd.py startSlideShow() to launch hdmi.py all fail:

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?

No ongoing inter-process communication is needed. Other than when the lcd.py program needs to "launch" the hdmi.py program, they do not need to communicate, and it does not really matter to me whether or not terminating lcd terminates the hdmi.py program.

Things I tried in startSlideShow() that do not work:

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

And

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

And

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>
jpw
  • 18,697
  • 25
  • 111
  • 187
  • 1
    Do you know what is getting shared between the two that you don't want? You mention environment variables but child processes do have their own set of environment variables, they just get initialized to the same value as the parent I believe. If the problem is that the two need a different value of DISPLAY then popen will allow you to specify the alternate value with the env argument to the popen constructor. You could also try spawning the child as a daemon: http://stackoverflow.com/questions/5772873/python-spawn-off-a-child-subprocess-detach-and-exit – Pace Jan 25 '16 at 16:30
  • using env= worked, thank you. if you want to add that as an answer I'll accept it. – jpw Jan 28 '16 at 01:30
  • How the question about different `$DISPLAY`s relates to *"as if it is being run from separate SSH terminals"* (the former is about envvars (pass `env` parameter), the latter is about `preexec_fn=os.setsid` (and possibly [other aspects that are usually common for daemons](https://www.python.org/dev/peps/pep-3143/#correct-daemon-behaviour)) – jfs Jan 29 '16 at 13:37

1 Answers1

2

In order to give the subprocess a different value for environment variables than the parent process you can use the env argument to the POpen constructor and supply the values you want. This should allow you, for example, to supply a different DISPLAY value.

Pace
  • 41,875
  • 13
  • 113
  • 156