import time import threading class test(threading.Thread): def __init__ (self): threading.Thread.__init__(self) self.doSkip = False self.count = 0 def run(self): while self.count<9: self.work() def skip(self): self.doSkip = True def work(self): self.count+=1 time.sleep(1) if(self.doSkip): print "skipped" self.doSkip = False return print self.count t = test() t.start() while t.count<9: time.sleep(2) t.skip()
Thread-safe in which way? I don't see any part you might want to protect here.
skip may reset the
doSkip at any time, so there's not much point in locking it. You don't have any resources that are accessed at the same time - so IMHO nothing can be corrupted / unsafe in this code.
The only part that might run differently depending on locking / counting is how many "skip"s do you expect on every call to
.skip(). If you want to ensure that every skip results in a skipped call to
.work(), you should change
doSkip into a counter that is protected by a lock on both increment and compare/decrement. Currently one thread might turn
doSkip on after the check, but before the
doSkip reset. It doesn't matter in this example, but in some real situation (with more code) it might make a difference.
Whenever the test of a mutex boolean ( e.g. if(self.doSkip) ) is separate from the set of the mutex boolean you will probably have threading problems.
The rule is that your thread will get swapped out at the most inconvenient time. That is, after the test and before the set. Moving them closer together reduces the window for screw-ups but does not eliminate them. You almost always need a specially created mechanism from the language or kernel to fully close that window.
The threading library has Semaphores that can be used to synchronize threads and/or create critical sections of code.
Apparently there isn't any critical resource, so I'd say it's thread-safe.
But as usual you can't predict in which order the two threads will be blocked/run by the scheduler.
This is and will thread safe as long as you don't share data between threads.
If an other thread needs to read/write data to your thread class, then this won't be thread safe unless you protect data with some synchronization mechanism (like locks).
To elaborate on DanM's answer, conceivably this could happen:
if self.doSkip: print 'skipped'
self.doSkip = False
In other words, while you might expect to see one "skipped" for every call to
t.skip(), this sequence of events would violate that.
However, because of your
sleep() calls, I think this sequence of events is actually impossible.
(unless your computer is running really slowly)