asynchronous - python interrupt infinite loop in exec'd script in thread -


a gui application allows user write python script, run (via exec). problem if user, mistake (i'm not concerned ill intention, honest coding mistakes on part of user) script contains infinite loop, control never return application. keyboard interrupt doesn't work because of gui.

i have identified 4 ways handle this:

  1. tracing: use sys.settrace function gets called @ every line; in there, put logic attempts identify if same segment of code being executed on , on (how challenging in practice don't know yet). guess slow down execution speed considerably.
  2. asynchronous exception: run script in separate thread and, using ctypes, have main thread use pythreadstate_setasyncexc raise exception in script thread kick out of loop (see https://gist.github.com/liuw/2407154 , http://tomerfiliba.com/recipes/thread2/). part of thread called exec recover control , take appropriate action (show message user etc). know, threads should not aborted outside here, if doing leaves objects being changed script in undefined state, @ least allow gui throw out objects no longer reliable (it can because modifications accessible script in 1 big object thrown out , reloaded disk).
  3. separate process: using multiprocessing module, run script in separate process; script can contain calls objects live in parent's main thread going quite complicated.
  4. daemonic thread: run script in daemonic thread, if script doean't return after period, consider "hung". when application exits, thread continue run , user can forcibly kill via task manager (or exiting thread could, raising systemexception or such).

so question: if have provide feature, 1 of above methods lesser of evils? there other techniques yet, not in above 4?

one way custom multiprocessing.manager object. can handle synchronization you. (link: multiprocessing)

here's example of having single instance, multiprocess processes able call methods on it. note i'm not using instance state, that's left reader :)

the original code passing "maths.add" (instance method) pool, methods aren't picklable. created global "my_add", accepts maths instance (which is pickable), numbers adds , results result.

source

from multiprocessing import pool multiprocessing.managers import basemanager  class mathsclass(object):     def add(self, x, y):         return x + y     def mul(self, x, y):         return x * y  class mymanager(basemanager):     pass  mymanager.register('maths', mathsclass)  def my_add(mobj, *args):     return mobj.add(*args)  if __name__ == '__main__':     manager = mymanager()     manager.start()     maths = manager.maths()      # pass shared 'maths' object each process      pool = pool()     print pool.apply(my_add, [maths, 4, 3])     # print maths.add(4, 3)         # prints 7     print pool.apply(my_add, [maths, 7, 8])     # print maths.mul(7, 8)         # prints 56 

output

7 15 

Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -