Read-Write Lock vs primitive Lock()

k3xji sumerc at gmail.com
Mon Dec 29 11:17:42 CET 2008


On 29 Aralık, 11:52, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Mon, 29 Dec 2008 05:56:10 -0200, k3xji <sum... 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)

No problem.:)

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

No just used for testing. It does not matter, what I want to see is
that I want to create a botleneck on readers.

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

If I put the for loop outside, in that case, readers will not overlap
at all, and you would be amazed by the numbers for that test. They
indicate primitive lock is faster than read-write lock, as it requires
the lock, executes only one bytecode operation and releases the lock.
So, in order to create a bottlenneck on readers, we need to somehow do
not release the lock immediately.

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

Yeah, you are right but it is irrelevant.

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

With that, primitive locks perform 10 times better than Read-Write
lock. See above.


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

This is just for testing. Suppose that I am actually reading the
value. I don't understand why a lock is not required? Are you saying
lock is not necesary beacuse GLOBAL_VALUE is an immutable object, if
then, suppose it is not. This is just a test. Suppose GLOBAl_VAR is a
list and we are calling append() on it which is nt an atomic
operation.

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

Unfortunately, I do not understand anyhing.

Thanks.




More information about the Python-list mailing list