views:

361

answers:

5

If I do somthing like this..

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()

..will it be thread save?

+2  A: 

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.

viraptor
A: 

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.

Bastien Léonard
A: 

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).

Martin
+1  A: 

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.

DanM
A: 

To elaborate on DanM's answer, conceivably this could happen:

  1. Thread 1: t.skip()
  2. Thread 2: if self.doSkip: print 'skipped'
  3. Thread 1: t.skip()
  4. Thread 2: self.doSkip = False
  5. etc.

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)

John Fouhy