jayshankar nair
jayshankar nair

Reputation: 69

Python threading lock is condition.acquire similar to lock.acquire

Is condition.acquire(threading.Condition()) similar to lock.acquire(threading.Lock). Does both of get access to the lock. Can i use condition.wait,notify with lock.acquire or i have to use condition.wait, notify with condition.acquire.

cond.acquire()  // can i replace with lock.acquire

   while count[ipID]> 1:
      cond.wait()
   if ipID == 0:
      time.sleep(10)


   count[ipID] = count[ipID] + 1


   cond.release() // can i replace with lock.release

Upvotes: 2

Views: 1627

Answers (2)

jayshankar nair
jayshankar nair

Reputation: 69

The notify part of code is as below.

print "count is %d %s" % (count[ipID],name)

   cond.acquire()

   count[ipID] = count[ipID] - 1
   cond.notifyAll()
   cond.release()

Upvotes: 2

abarnert
abarnert

Reputation: 365607

If your condition was created like this:

lock = Lock()
cond = Condition(lock)

… then yes, as the docs explain, cond.acquire() is just calling lock.acquire(), so you could do that instead and get the same effect. And likewise for release. However, it's likely to be misleading to human readers (and maybe to static analysis tools), so unless you have a really good reason, you shouldn't do it.


On the other hand, if they're unrelated objects, created like this:

lock = Lock()
cond = Condition()

… then no. It is illegal to call cond.wait() if you haven't acquired the lock used by the condition. It's guaranteed to raise a RuntimeError. It doesn't matter if some other Lock object happens to be ensuring that nobody else will access cond; the whole point of cond.wait is that it atomically releases its lock and blocks on notify, so if it's not holding its lock, it's useless as a condition.


As a side note, it's almost always better to acquire both Locks and Conditions in a with statement:

with cond:
    with count[ipID] > 1:
        cond.wait()
    if ipID == 0:
        time.sleep(10)
    count[ipID] = count[ipID] + 1

The way you've written things, if anything after that acquire raises an exception, you will never release the condition, so no other thread waiting on it can wake up.

While we're at it, using sleep is almost always a sign of a problem with your threading design. Why can't you just wait(timeout=10) instead? If you have too many spurious notify calls, you should fix that. If count[ipID] is not getting reset properly so the while loop may exit early, that's even more important to fix. Whatever problem you think you're solving with sleep, you're probably just disguising it.

Upvotes: 3

Related Questions