2

Hi I'm new to Python and multithreaded programming. I have a script running through some test steps. Meanwhile this is running I want to create a thread that polls with an interval and reads if any processes have crashed during execution. I have a function which acquires this information. My problem is how I can throw an exception from that thread whenever I get that a process has crashed. My current thread looks something like this:

class process_thread(threading.Thread):
  def __init__(self):
  threading.Thread.__init__(self)
  self.run_thread = True

  def run(self):
    while self.run_thread:
      if has_any_processes_crashed() == -1:
        self.run_thread = False
        raise MyStopException("A process has crashed") # This is the problematic line. It is only raised in this thread, not in main thread.
      else:
        time.sleep(3)

The problem is however that the exception is only raised in that thread and not in the main thread. I want to throw the same exception there and exit the script. What I do with this thread is that I create an object before I start with all my test steps and set it as a Daemon thread. When my test steps are done I want to kill this thread before shutting down the simulation. All this is done by:

p_thread = process_thread()
p_thread.setDaemon(True)
p_thread.start()

# Executing all test steps here
# test_step_1
do_something_1()
# test_step_n
do_something_n()

p_thread.run_thread = False
p_thread.join()

I do not think that a Queue is possible in my scenario as I still need to execute my test steps in the main thread.

Any help is appreciated!

C Arvidson
  • 21
  • 1
  • 4

1 Answers1

1

You can save the exception as a variable using the traceback module. In your thread that you are running and expect the exception, try:

import traceback

class process_thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.run_thread = True

    def run(self):
        try:
            process that may crash()
        except:
            self.exception_var = traceback.format_exc()

The you access the variable in the main thread:

print(self.exception_var)

Or whatever you want to do with it here. Bear in mind, without seeing how your processes crash, i'm not sure this is exactly what you want. This does require that the processes that crash actually cause an exception, hence using traceback. If they don't, then you may have to manually raise an exception. There is a great answer on doing that here: Manually raising (throwing) an exception in Python

Community
  • 1
  • 1
Nick H
  • 1,081
  • 8
  • 13
  • This does not solve my problem as I would have to frequently ask this variable if it has gotten any exception. Then I will not gain anything from the thread as I can just call a regular function to get this information. I need something that raises an exception in the main thread from the created daemon thread. – C Arvidson Feb 28 '17 at 12:58
  • Ok, have you tried the method `thread.interrupt_main()`, this will trigger a `KeyboardInterrupt` in the main thread. Link here: https://docs.python.org/2/library/thread.html#thread.interrupt_main – Nick H Feb 28 '17 at 14:59
  • Thank you, that was exactly what I was after as I have not found anything about raising my self-defined exception. Thumbs up – C Arvidson Mar 01 '17 at 11:56
  • Great, glad it helps – Nick H Mar 01 '17 at 12:06