Regardless of the fact that I use Kivy and Python3, I am trying to raise an exception in one process and catch it in another. The process Trigger is the one raising the exception, The processes 1 and 2 are catching it. I took a look at the solution using pipe but in my case the processes that are catching can execute different functions, sub-processes and so on. So I gave a try with multiprocessing.Queue()
. So far I can raise the exception in Trigger but I can not pass it over to Process2 or Process1. The script ends with no errors at all, seems like there is no communication between the processes. Where is the error?
The code:
#!/usr/bin/python3 python3
# -*- coding: utf-8 -*-
# common modules
import time, os
import signal
import multiprocessing
from multiprocessing import Process
import queue
import subprocess
# set environment variables to avoid "segmentation error" due to raspbian version
os.environ["KIVY_WINDOW"] = "sdl2"
os.environ["KIVY_GL_BACKEND"] = "sdl2"
os.environ["KIVY_IMAGE"] = "sdl2"
from kivy.core.window import Window
Window.show_cursor = True
# kivy modules first, if not Kivy may cause problems
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
kivy.require('2.0.0')
def signal_handler(signal, frame):
exit(0)
def Trigger(q):
try:
for y in range(6):
print("trigger raise in", y)
time.sleep(1) # debounce for 100 ms
raise Exception("trigger on ------------")
except Exception as e:
print("exception in trigger:", e)
e = q.put(e)
def Process1(q):
# run ref search
try:
while True:
print("process 1")
time.sleep(1)
except Exception as e:
e = q.get()
print("Function1 exception:", e)
raise e
# main screen
class MainScreen(Screen):
def __init__(self, **kwargs):
self.name="MAIN SCREEN"
super(Screen, self).__init__(**kwargs)
# main app class
class Process2(App):
def Function1(self):
# run ref search
try:
for x in range(10):
print("range 30", x)
time.sleep(1)
except Exception as e:
e = q.get()
print("exception in function 1:", e)
raise e
def Function2(self):
# run ref search
try:
while True:
print("endless")
time.sleep(1)
except Exception as e:
e = q.get()
print("exception in function 2:", e)
raise e
def build(self):
sm = Builder.load_string("""
ScreenManager:
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
size: self.size
MainScreen:
name: "MainScreen"
size_hint: 1, 1
auto_dismiss: True
# auto_dismiss: False # original line
title: "title"
title_align: "center"
BoxLayout:
orientation: "vertical"
spacing: 10
BoxLayout:
orientation: "horizontal"
spacing: 5
size_hint: 1, .5
Button:
font_size: 30
text: "button 1"
Button:
font_size: 30
text: "button 2"
BoxLayout:
orientation: "horizontal"
spacing: 10
size_hint: 1, .5
""")
self.Function1()
self.Function2()
# main ##################################################
if __name__ == '__main__':
#CTRL+C signal handler
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
q = multiprocessing.Queue()
global p1, p2, p0
# lauch trigger to raise exception
p0 = Process(target=Trigger, args=(q,))
p0.daemon = True
p0.start()
#launch process 1
p1 = Process(target=Process1, args=(q,))
p1.daemon = True
p1.start()
#launch Kivy
p2 = Process(target=Process2().run(), args=(q,))
p2.start()
p2.join()