×

Discussion Board

Results 1 to 10 of 10
  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Writing an image to file in a worker thread

    Hello folks,

    I'm hitting a problem that is difficult to diagnose as it kills Python when running on the phone. Basically (if I lose you, shout), I have a Queue which is monitored by a thread pool. I shove an image onto the queue, a thread pops it off the queue and then writes it to file. This works the first time but subsequent writes fall over, even though the save is wrapped around some exception handling. Um.

    Here's the worker thread code:

    Code:
    class FileWorker(threading.Thread):
        def run(self):
            while True:
                img = imgpool.get()
                if img != None:
                    tm = localtime()
                    fn = "e:\\Images\\img%02d%02d%02d%02d.jpg" % (tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec)
                    try:
                        # if I remove this line, the program continues... demons!
                        img.save(filename=fn, quality=100)
                    except:
                        # Do something sensible
                        pass
    imgpool is populated with stuff from another method in the main application code:

    Code:
    def take_photo(self):
            img = camera.take_photo(mode="RGB", flash="auto", size=self.image_size)
            imgpool.put(img)
            w, h = self.canvas.size
            self.canvas.blit(img, target=(0, 0, w, 0.75 * w), scale=1)
    I did have a 'print' statement in the exception handling code to aid debugging but that isn't called; the app just dies. Or, even better, if I exit the app after exercising the code once (whereby an image is saved), the Python shell will crash when I click the options button. There's really no need for that now, is there?

    Any ideas? Need more info? Ever wondered what mice look like with no ears?! Oh, this is on an N97 running (glances at phone)... Python 1.9.6. This is some ever so slightly silly idea to speed up the main processing because writing to file is sooooo slow.

    My thanks in advance. Unless of course you can't help me.

    - spaceyjase

  2. #2
    Super Contributor
    Join Date
    Nov 2007
    Location
    Sertaozinho/Brazil
    Posts
    768

    Re: Writing an image to file in a worker thread

    My suggestion:

    Log the exception to a file, like:

    Code:
    f = open('e:\\debug.log','at')
    try:
        something buggy here
    except Exception, e:
        f.write(unicode(e)+"\n")
        f.flush()
    Multithread programs are a pain ...

  3. #3
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    151

    Re: Writing an image to file in a worker thread

    Maybe you could pepper the code with audio.say("string here") events, perhaps follow each one with a second of sleep time (e32.ao_sleep(1))

    That way you get audible confirmation as the program progresses, and you can check where it goes silent. You could even get audio.say to read the error out loud!

  4. #4
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Re: Writing an image to file in a worker thread

    Ah, that is indeed an excellent suggestion. Alas, I modified the code accordingly and I get a zero byte file; it doesn't appear to even enter the exception code.

    I will work on a complete but small example script and upload it so perhaps someone else can confirm I'm not mentally unstable?

    Thanks

    - spaceyjase

    Quote Originally Posted by marcelobarrosalmeida View Post
    My suggestion:

    Log the exception to a file, like:

    Multithread programs are a pain ...

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Re: Writing an image to file in a worker thread

    Okey-dokey, here's a (quickly knocked up) example. It will take a picture when the timer expires but then when the timer expires a second time, the shell will crash. Note there's sweet Fanny Adams in the log.

    Probably something obvious?

    Code:
    from time import localtime
    import appuifw
    import camera
    import graphics
    import key_codes
    import e32
    import Queue
    import threading
    
    class FileWorker(threading.Thread):
    	def run(self):
    		# run forever!
    		while True:
    			# Get an img to write from the queue
    			img = imgpool.get()
    			if img != None:
    				f = open('e:\\debug.log','at')
    				try:
    					tm = localtime()
    					fn = "e:\\Images\\nct_img%02d%02d%02d%02d.jpg" % (tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec)
    					img.save(filename=fn, quality=100)
    				except Exception, e:
    					f.write(unicode(e)+"\n")
    					f.flush()
    
    class App:
    	def __init__(self):
    		self.time_delay = 10
    		# set application specifics
    		self.old_app_body = appuifw.app.body
    		appuifw.app.body = self.canvas = appuifw.Canvas()
    		appuifw.app.title = u"Testing"
    		appuifw.app.screen = "normal"
    		# clear the screen
    		self.canvas.clear(0)
    		# set exit handler to break lock...
    		self.old_exit_handler = appuifw.app.exit_key_handler
    		appuifw.app.exit_key_handler = self.exit_handler
    		# get a lock and timer
    		self.lock = e32.Ao_lock()
    		self.timer = e32.Ao_timer()
    		# start worker threads
    		for x in xrange(5):
    			FileWorker().start()
    		# initialise camera
    		camera.start_finder(self.camera_blit)
    		# start timer to continue processing 
    		self.timer.after(self.time_delay, self.timer_expired)
    		# now wait for exit
    		self.lock.wait()
    
    	def camera_blit(self, img):
    		self.canvas.blit(img)
    
    	def take_photo(self):
    		w, h = self.canvas.size
    		img = camera.take_photo(mode="RGB", flash="auto")
    		imgpool.put(img)
    
    	def timer_expired(self):
    		self.take_photo()
    		self.timer.after(self.time_delay, self.timer_expired)
    
    	def exit_handler(self):
    		self.timer.cancel()
    		camera.stop_finder()
    		camera.release()
    		self.canvas = None
    		appuifw.menu = []
    		appuifw.app.body=self.old_app_body
    		appuifw.app.exit_key_handler = self.old_exit_handler
    		self.lock.signal()
    
    # queue of images to write
    imgpool = Queue.Queue(0);
    App()
    Last edited by spaceyjase; 2009-08-17 at 21:55. Reason: forum br0k3d my code

  6. #6
    Super Contributor
    Join Date
    Nov 2007
    Location
    Sertaozinho/Brazil
    Posts
    768

    Re: Writing an image to file in a worker thread

    Hi

    Using ErrRD (http://www.getjar.com/products/26398/errrd), I discovered the error message:

    E323User-CBase 46

    However, this error is obscure for me. Some references:

    E32USER-CBase 46 panic is raised by the Active Scheduler due to a stray signal. A stray signal is a technical term for a situation when the Active Scheduler is signalled upon an outstanding asynchronous request having been completed, but it (i.e. the Active Scheduler) cannot find any active objects ready for handling the request.
    I think It is the most appropriate explanation for stray signal , Just try to figure out error where is it in your code ,if couldn't post your whole code here

    http://www.newlc.com/en/forum/active...2user-cbase-46


    For Stray signal (E32USER-CBase 46)there will be only one of three reasons:-
    1. CActiveScheduler::Add() was not called when the active object was constructed.
    2. SetActive() was not called following the submission of a request to the asynchronous service provider.
    3. The asynchronous service provider completed the TRequestStatus of an active object more than once – either because of “when an already-completed request is cancelled” or ”more than one request was submitted simultaneously on the same active object."

    http://www.newlc.com/forum/regarding-e32user-cbase-46


  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Re: Writing an image to file in a worker thread

    Blimey, thanks for that. The problem is in the interpreter, perhaps? Reading through the linked thread says:

    Whenever you make a asynchronous call, please make sure that the variable holding the result
    remain valid until you have been notified that the request is completed
    Which seems plausible; perhaps something internal to the file writer is going out of scope? I don't see how but I'll have a tinker and see if I can't stumble onto a solution; perhaps there's a concurrency issue using 'img' as I have. Perhaps I'm going about this the wrong way and could launch file writer threads on the fly when some work needs doing (that feels wrong but, you know).

    Thank you for the help!

    - spacejase

  8. #8
    Super Contributor
    Join Date
    Nov 2007
    Location
    Sertaozinho/Brazil
    Posts
    768

    Re: Writing an image to file in a worker thread

    I tried the following before enqueuing:

    Code:
    import copy
    imgpool.put(copy.deepcopy(img))
    But ...

    Code:
    copy.Error: un(deep)copyable object of type <type 'graphics.Draw'>


    Better to report the problem at Pys60/Maemo.

    Marcelo

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Re: Writing an image to file in a worker thread

    Ah, great minds

    Code:
    imgpool.put(copy(img))
    But this appears to have the same result, deep copy has error you reported. Blast!

    I think you're correct and will proceed to report it

  10. #10
    Registered User
    Join Date
    Aug 2009
    Posts
    6

    Re: Writing an image to file in a worker thread

    Right, reported the bug. Idle curiousity lead me to try...

    Code:
    thread.start_new_thread(self.file_write, (img))
    ...with a method body as the run definition.

    But this appears to be broken too (I get same results as: #2700402). Hrmph.

Similar Threads

  1. S60 5th Edition Emulator Crashes
    By Yagiza in forum Symbian Tools & SDKs
    Replies: 26
    Last Post: 2010-08-07, 21:24
  2. Problem with pyobfuscate
    By JOM in forum Symbian
    Replies: 3
    Last Post: 2008-06-20, 22:47
  3. Contacts fields order??
    By timatima in forum Symbian
    Replies: 1
    Last Post: 2007-06-08, 13:51
  4. how to cut some part of Image
    By mshouab in forum Mobile Java Media (Graphics & Sounds)
    Replies: 2
    Last Post: 2006-08-04, 09:05
  5. Replies: 1
    Last Post: 2005-05-26, 14:22

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×