473,388 Members | 1,526 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

threading.Event usage causing intermitent exception

Admittedly this problem causes no actual functional issues aside from
an occasional error message when the program exits. The error is:

Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:

Yes all that info is blank. The application is a console application
that is waiting for some condition on the machine to happen. However,
I leave open the possiblitiy to cancel by a single key press at which
point the program terminates. Suffice it to say, I cannot perform both
checks without invoking threads as the key press gets "missed"
sometimes. Below is a simplification of the code

canceled = False
myEvent = threading.Event()

def watchForCancel()
global canceled
# turn of terminal buffering and capture key presses here
canceled = True
myEvent.set()
def watchForCondition()
# do a bunch of stuff checking the system
myEvent.set()

cancelThread = threading.Thread(target = watchForCancel)
cancelThread.setDaemon(True) # so I can exit the program when I want
to
cancelThread.start()
conditionThread = threading.Thread(target = watchForCondition)
conditionThread.setDaemon(True)
conditionThread.start()

myEvent.wait()

if cancelled:
sys.exit(2)

# do more stuff if the condition returned instead of cancel and then
I'm done
I've left out most of the active code, just cuz I think it muddies the
water. Now about 9 out of 10 times this works just fine. However,
every once in a while I get the exceptions mentioned above, but only
when I cancel out of the operation. I think the conditionThread is in
the process of shutting down and gets hosed up somehow and spits out an
exception, but the interpreter no longer has access to the info since
it is shutting down. I know that the condition is not being met in
these situations, since the condition is based on a network client
sending a certain set of data, and in my tests I know that no client
has sent said data. I haven't worried about this too much, as it
doesn't cause any functional problems, but it really irritates me. I
suppose I could make the threads aware of each other, but that just
seems stupid. Any suggestions on how to eliminate this intermittent
error?

Thanks

Aug 8 '06 #1
2 2041
[ak*********@gmail.com]
Admittedly this problem causes no actual functional issues aside from
an occasional error message when the program exits. The error is:

Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:

Yes all that info is blank.
That's typical when the interpreter has torn so much of itself down
that there's not enough left in the `sys` module even to print
exception info gracefully. The easiest way to stop that is to stop
/trying/ to run Python code while the interpreter is tearing itself
down.
The application is a console application that is waiting for some
condition on the machine to happen. However, I leave open the
possiblitiy to cancel by a single key press at which
point the program terminates. Suffice it to say, I cannot perform both
checks without invoking threads as the key press gets "missed"
sometimes. Below is a simplification of the code

canceled = False
myEvent = threading.Event()

def watchForCancel()
global canceled
# turn of terminal buffering and capture key presses here
canceled = True
myEvent.set()
Presumably this is some kind of poll-and-sleep loop? If so, add a
check to get out of the loop if myEvent.isSet(). Or if not, make it
some kind of poll-and-sleep loop ;-)
def watchForCondition()
# do a bunch of stuff checking the system
myEvent.set()
Ditto.
cancelThread = threading.Thread(target = watchForCancel)
cancelThread.setDaemon(True) # so I can exit the program when I want to
And get rid of that. The comment doesn't make sense to me, and
forcing a thread to be a daemon is exactly what /allows/ the thread to
keep running while the interpreter is tearing itself down. That's why
"daemonism" isn't the default: it's at best delicate. I don't see a
real reason for wanting this here.
cancelThread.start()
conditionThread = threading.Thread(target = watchForCondition)
conditionThread.setDaemon(True)
Ditto.
conditionThread.start()

myEvent.wait()

if cancelled:
sys.exit(2)

# do more stuff if the condition returned instead of cancel and then
I'm done
I've left out most of the active code, just cuz I think it muddies the
water. Now about 9 out of 10 times this works just fine. However,
every once in a while I get the exceptions mentioned above, but only
when I cancel out of the operation. I think the conditionThread is in
the process of shutting down and gets hosed up somehow and spits out an
exception, but the interpreter no longer has access to the info since
it is shutting down.
At this point it's likely that even sys.stdout and sys.stderr no
longer exist. The "Unhandled exception" message is printed directly
to the C-level `stderr` instead.
...
I suppose I could make the threads aware of each other, but that just
seems stupid. Any suggestions on how to eliminate this intermittent
error?
Stop forcing them to be daemon threads. The interpreter won't start
to tear itself down then before both threads terminate on their own.
To arrange for that, it's not necessary for the threads to become
aware of each other, but it is necessary for the threads to become
aware of another (shared) reason /for/ exiting. The most natural way
to do that, given what you said above, is to make both threads aware
that their shared myEvent event may get set "externally", and to stop
when they find it has been set.
Aug 8 '06 #2

Tim Peters wrote:
[ak*********@gmail.com]
Admittedly this problem causes no actual functional issues aside from
an occasional error message when the program exits. The error is:

Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:

Yes all that info is blank.

That's typical when the interpreter has torn so much of itself down
that there's not enough left in the `sys` module even to print
exception info gracefully. The easiest way to stop that is to stop
/trying/ to run Python code while the interpreter is tearing itself
down.
The application is a console application that is waiting for some
condition on the machine to happen. However, I leave open the
possiblitiy to cancel by a single key press at which
point the program terminates. Suffice it to say, I cannot perform both
checks without invoking threads as the key press gets "missed"
sometimes. Below is a simplification of the code

canceled = False
myEvent = threading.Event()

def watchForCancel()
global canceled
# turn of terminal buffering and capture key presses here
canceled = True
myEvent.set()

Presumably this is some kind of poll-and-sleep loop? If so, add a
check to get out of the loop if myEvent.isSet(). Or if not, make it
some kind of poll-and-sleep loop ;-)
after setting up the terminal correctly, ie changing buffering settings
etc. (I want to cancel with a single key-press with no "return" hit.
This was suprisingly difficult to do. The wait code is simply:

while keyPressed != 'q':
keyPressed = sys.stdin.read(1)

The really annoying thing here, is that I cannot put in any other steps
in the while loop without sometimes missing the key press. I have to
unbuffer the terminal(otherwise the read doesn't return until the enter
key is pressed), and for whatever reason performing any action no
matter how trivial leads to missing the key stroke on occasion - that's
why I pursued the daemon route.
>
def watchForCondition()
# do a bunch of stuff checking the system
myEvent.set()

Ditto.
cancelThread = threading.Thread(target = watchForCancel)
cancelThread.setDaemon(True) # so I can exit the program when I want to
The conditional thread will never terminate without making the threads
aware of eachother. Setting them daemon allows the interpreter to
shutdown with one of them running - and ocaisonally cuases the error.
What I find interesting, the behavior only happens when I cancel, not
when the condition is reached.
And get rid of that. The comment doesn't make sense to me, and
forcing a thread to be a daemon is exactly what /allows/ the thread to
keep running while the interpreter is tearing itself down. That's why
"daemonism" isn't the default: it's at best delicate. I don't see a
real reason for wanting this here.
cancelThread.start()
conditionThread = threading.Thread(target = watchForCondition)
conditionThread.setDaemon(True)

Ditto.
conditionThread.start()

myEvent.wait()

if cancelled:
sys.exit(2)

# do more stuff if the condition returned instead of cancel and then
I'm done
I've left out most of the active code, just cuz I think it muddies the
water. Now about 9 out of 10 times this works just fine. However,
every once in a while I get the exceptions mentioned above, but only
when I cancel out of the operation. I think the conditionThread is in
the process of shutting down and gets hosed up somehow and spits out an
exception, but the interpreter no longer has access to the info since
it is shutting down.

At this point it's likely that even sys.stdout and sys.stderr no
longer exist. The "Unhandled exception" message is printed directly
to the C-level `stderr` instead.
exactly - giving me no way to swallow it.
...
I suppose I could make the threads aware of each other, but that just
seems stupid. Any suggestions on how to eliminate this intermittent
error?

Stop forcing them to be daemon threads. The interpreter won't start
to tear itself down then before both threads terminate on their own.
To arrange for that, it's not necessary for the threads to become
aware of each other, but it is necessary for the threads to become
aware of another (shared) reason /for/ exiting. The most natural way
to do that, given what you said above, is to make both threads aware
that their shared myEvent event may get set "externally", and to stop
when they find it has been set.
Due to the oddities of capturing that keypress at the console, I
suspect I can un-daemonize the conditional thread and check for
cancelled=True and have it return. Since the error only occurs when
the conditional thread is still running, undaemonizing it will prevent
that and allow the interpreter to shut down more gracefully.

Thanks for the advice.

Aug 9 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

77
by: Jon Skeet [C# MVP] | last post by:
Please excuse the cross-post - I'm pretty sure I've had interest in the article on all the groups this is posted to. I've finally managed to finish my article on multi-threading - at least for...
8
by: Michael Culley | last post by:
I have some code that returns an event on a different thread. This is causing all sorts of problems, so I would like to just call a method on the main thread of the app and eliminate the second...
2
by: Nicholas | last post by:
I have this class that provides a disk-based queue for storing various items. As items are queued the event delegate is called and the consumer dequeues the object and processes it. This seems to...
11
by: Tyler Sample | last post by:
I've been having strange thread conflicts, and after moving the relevant mutex higher and higher I've finally determined that the mutex doesn't seem to be working at all. Here is the relevant...
0
by: Colmeister | last post by:
I recently read Jason Clark's excellent article on Unhandled Exceptions (http://msdn.microsoft.com/msdnmag/issues/04/06/NET/default.aspx) and have attempted to incorporate the features he talks...
12
by: Perecli Manole | last post by:
I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse. I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock...
5
by: venkat | last post by:
Hi, I have a page that calls a sql procedure and it runs for 20 - 40 min. I use usual threading for this page. <code>Thread objthread = new Thread(new ThreadStart(ticketingThread));...
0
by: kingcrowbar.list | last post by:
Hello Everyone I have been playing a little with pyGTK and threading to come up with simple alert dialog which plays a sound in the background. The need for threading came when in the first...
5
by: JasonX | last post by:
Im having problems with my program, in that if I close the main form while my new thread is doing work which involves writing to the main form, then I get an error about a disposed object. To...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.