Interesting Thread Gotcha

Dan thermostat at gmail.com
Tue Jan 15 10:50:42 EST 2008


On Jan 15, 10:07 am, "Hendrik van Rooyen" <m... at microcorp.co.za>
wrote:
> I thought I would share this nasty little gotcha with the group.
>
> Consider the following code fragment:
>
> <start>
> print 'starting kbd thread'
> keyboard_thread = thread.start_new_thread(kbd_driver (port_q,kbd_q))
> print 'starting main loop'
> error = Mainloop(s,port_q,active_q_list)
> <end>
>
> It produces, as output, the following:
>
> starting kbd thread
> we get here - a
>
> It does not print 'starting main loop', the Mainloop routine
> is never executed, and no exceptions are raised.
>
> Here is the offending routine that seems to capture the control:
>
> <start>
> def kbd_driver(out_q,in_q):
>     """
>     thread to look for keyboard input and to put it on the queue out_q
>     also looks for replies on in_q and prints them
>     """
>
>     kbdname = '/dev/stdin'
>
>     kbd  = open(kbdname,'r+',1) # Reading, line buffered
>
>     unblock(kbd)     # Call the magic to unblock keyboard
>     print 'we get here - a'
>     while True:
>
>         try:
>             d = kbd.readline()  # see if any kbd input
>         except:
>             IOError
>             try:
>                 msg=in_q.get(block=False)
>             except Queue.Empty:
>                 time.sleep(0.1)
>                 continue
>             print msg
>             time.sleep(0.1)
>             continue
>         d = d.rstrip()    # get rid of line feed
>         out_q.put([d + '\r',in_q]) # add a carriage return and return q and send
> to port
> <end>
>
> The unblock is a routine that unblocks a port using fcntl - it
> is not the problem.  In case you don't believe me, here it is:
>
> def unblock(f):
>  """Given file 'f', sets its unblock flag to true."""
>
>     fcntl.fcntl(f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
>
> I will post the solution tomorrow when I read my mail,
> if no one has spotted it by then.
>
> - Hendrik

>>> keyboard_thread = thread.start_new_thread(kbd_driver (port_q,kbd_q))

Needs to be
>>> keyboard_thread = thread.start_new_thread(kbd_driver, (port_q,kbd_q))

Commas are important!

-Dan



More information about the Python-list mailing list