Read-Write Lock vs primitive Lock()

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Mon Dec 29 04:52:16 EST 2008


En Mon, 29 Dec 2008 05:56:10 -0200, k3xji <sumerc at gmail.com> escribió:

> I  am trying to see on which situations does the Read-Write Lock
> performs better on primitive Lock() itself. Below is the code I am
> using to test the performance:
> import threading
> import locks
> import time
>
> class mylock(object):

(I'm not convinced your lock is correct)

> GLOBAL_VAR = 1
> #GLOBAL_LOCK = locks.ReadWriteLock()
> GLOBAL_LOCK = threading.Lock()
> #GLOBAL_LOCK = mylock()
> GLOBAL_LOOP_COUNT = 100000
> GLOBAL_READER_COUNT = 1000
> GLOBAL_WRITER_COUNT = 1

Only one writer? If this is always the case, you don't need a lock at all.

> class wthread(threading.Thread):
>     def run(self):
>             try:
>                 #GLOBAL_LOCK.acquireWrite()
>                 #GLOBAL_LOCK.acquire_write()
>                 GLOBAL_LOCK.acquire()
>                 for i in range(GLOBAL_LOOP_COUNT):
>                     GLOBAL_VAR = 4
>             finally:
>                 #GLOBAL_LOCK.release_write()
>                 GLOBAL_LOCK.release()

Note that the thread acquires the lock ONCE, repeats several thousand
times an assignment to a *local* variable called GLOBAL_VAR (!), finally
releases the lock and exits. As every thread does the same, they just run
one after another, they never have a significant overlap.

Also, you should acquire the lock *before* the try block (you have to
ensure that, *after* acquiring the lock, it is always released; such
requisite does not apply *before* acquiring the lock)

I'd test again with something like this:

class wthread(threading.Thread):
      def run(self):
          global GLOBAL_VAR
          for i in xrange(GLOBAL_LOOP_COUNT):
              GLOBAL_LOCK.acquire()
              try:
                  GLOBAL_VAR += 1
              finally:
                  GLOBAL_LOCK.release()

> class rthread(threading.Thread):
>     def run(self):
>             try:
>                 #GLOBAL_LOCK.acquireRead()
>                 #GLOBAL_LOCK.acquire_read()
>                 GLOBAL_LOCK.acquire()
>                 for i in range(GLOBAL_LOOP_COUNT):
>                     GLOBAL_VAR = 3
>             finally:
>                 #GLOBAL_LOCK.release_read()
>                 GLOBAL_LOCK.release()

Hmmm, it's a reader but attempts to modify the value?
You don't have to protect a read operation on a global variable - so a
lock isn't required here.

> What I am doing is: I am creating multiple readers and try to do
> something. I had assumed that with using primitive Lock() on the above
> situation, it will create a bottleneck on the rthreads. But the
> numbers indicate that there are no difference at all. I had
> implemented my own READ-WRIET lock as can be seen above mylock and
> also used the one here: code.activestate.com/recipes/502283/.

I hope you now understand why you got the same numbers always.

-- 
Gabriel Genellina




More information about the Python-list mailing list