Evade polling when accessing Matlab from Python -
i access matlab python (on windows, remotely , via com-interface). goal is: matlab doing work , permanently changes value of variable. need know when value exceeds constant. right now, i'm polling matlab value of variable in indefinite loop breaks on exceeding value. however, let matlab work , tell me when case, while i'm lazily sitting there listening. there way achieve this, , how done best? have thought of defining callback function i'm passing matlab, on exceed-event triggers break out of non-busy-wait-loop in python, doubt work. i'm not experienced neither in matlab nor python, cues appreciated.
there's lot of other code involved, right like
connecttomatlab(*args) while true: val = getvaluefrommatlab() if val > constant or timeout: break what have in mind is
def breakloop(): ... connecttomatlab(breakloop, *args) while true: time.sleep(1) # or alternate non-busy-wait and let matlab invoke breakloop() upon val > constant. however, don't know if possible let matlab callback , if yes, how implement such breakloop()-function.
you can go other way, , use file system way pass messages between matlab , python.
inside matlab code, each time change variable, check if exceed threshold. if does, create new file in predetermined location. think of triggering event.
now inside python code, use of available ways listen changes in file system, , respond indicating variable break loop.
edit
here skeleton of solution proposed:
matlab_script.m
%# directory python code watching modifications dirpath = 'some_directory'; x = 0; i=1:1000 %# lengthy operation pause(0.5) x = x + 1; %# check if variable exceeds threshold if x > 10 %# save workspace mat-file inside directory watched. %# shall trigger notification in python save( fullfile(dirpath,'out.mat') ) break end end python_code.py
import os, sys, time import win32file, win32event, win32con # stub functions in case def connecttomatlab(): pass def getvaluefrommatlab(): return 99 # path predetermined directory watch dirpath = "some_directory" dirpath = os.path.abspath(dirpath) # start/connect matlab session, running script above connecttomatlab() # set folder watching (notify on file addition/deletion/renaming) print "started watching '%s' @ %s" % (dirpath, time.asctime()) change_handle = win32file.findfirstchangenotification( dirpath, 0, win32con.file_notify_change_file_name) # time-out in 10 sec (win32event.infinite wait indefinitely) timeout = 10000 try: # block/wait notification result = win32event.waitforsingleobject(change_handle, timeout) # returned because of change notification if result == win32con.wait_object_0: # retrieve final result matlab print "maltab variable has exceeded threshold @ %s" % time.asctime() val = getvaluefrommatlab() # timed out elif result == win32con.wait_timeout: print "timed-out after %s msec @ %s" % (timeout,time.asctime()) val = none # maybe indicate failure finally: # cleanup win32file.findclosechangenotification(change_handle) # work val print val the waitforsingleobject function start checking state of specified object. if nonsignaled, calling thread enters efficient wait state , consumes little processor time while waiting until object signaled (or time-out interval elapses).
you see when thread references object in non-signaled state, there immediate context switch i.e. taken down processor , put wait/sleep mode. later when object signaled, thread put runnable queue , ready execution.
in kind of waiting there no wastage of cpu cycles in wait state, although there overhead in context switching.
compare against "poll-and-wait" approach, thread waits , checks state of object of interest in kind of loop. known spin or busy wait, can prove wastage of cpu cycles.
now pywin32 module, can use use waitfor... functions directly. implementation should straightforward port of standard example given in msdn.
alternatively can use pyqt library qfilesystemwatcher class instead of directly using win32 api.
Comments
Post a Comment