Scoped Lock

M

Marco Bubke

Hi

There is the Lock object in the threading module.
But there is no medode there I could aquire a scoped
lock like:

mutex = threading.Lock()
my_lock = mutex.scoped_acquire() # maybe scoped_lock()
#now this stuff is locked

del mylock

#the lock is released.

def do_domething:
my_lock = mutex.scoped_acquire()
#now this stuff is locked
#the lock is released after its out of scope


I have written this my own but I'm not sure there is a drawback
because its looks so convinent. So I wonder why its not in
the module?

thx

Marco
 
Y

Ype Kingma

Marco said:
Hi

There is the Lock object in the threading module.
But there is no medode there I could aquire a scoped
lock like:

mutex = threading.Lock()
my_lock = mutex.scoped_acquire() # maybe scoped_lock()
#now this stuff is locked

del mylock

#the lock is released.

def do_domething:
my_lock = mutex.scoped_acquire()
#now this stuff is locked
#the lock is released after its out of scope


I have written this my own but I'm not sure there is a drawback
because its looks so convinent. So I wonder why its not in
the module?

Some reasons:
- What should happen when an exception happens during the locked stuff?
- It is possible pass a reference to the lock during the locked stuff,
so although the lock goes out of local scope, there still might be
a reference to it.
- The moment that __del__() is called is not guaranteed.

You can also do it like this:

mutex = threading.Lock()
mutex.acquire()
try:
# now this stuff is locked
finally:
mutex.release() # explicit is better than implicit

Regards,
Ype

email at xs4all.nl
 
M

Marco Bubke

Ype said:
Some reasons:
- What should happen when an exception happens during the locked stuff?
- It is possible pass a reference to the lock during the locked stuff,
so although the lock goes out of local scope, there still might be
a reference to it.
- The moment that __del__() is called is not guaranteed.

You can also do it like this:

mutex = threading.Lock()
mutex.acquire()
try:
# now this stuff is locked
finally:
mutex.release() # explicit is better than implicit

This does not look nice to me. There should be something me easily.
Maybe that:

def do_something() lock(mutex):
#this stuff is locked by the mutex

So you don't forget to release the lock.

best regards

Marco
 
D

Daniel Dittmar

Marco said:
This does not look nice to me. There should be something me easily.
Maybe that:

def do_something() lock(mutex):
#this stuff is locked by the mutex

So you don't forget to release the lock.

You could create a class that locks the mutex in the constructor and unlocks
it in the __del__ method.

class ScopedLock:
def __init__ (self, mutex):
self.mutex = mutex
mutex.acquire()

def __del__ (self):
self.mutex.release ()

use as
def do_something():
lock = ScopedLock (mutex)
# do something
# lock will be automatically released when returning


This works only in the current implementation of CPython where local
variables are usually (*) deleted when they fall out of scope.

(*) usually: unless they are returned or added to another object

And I guess with metaclasses, you can achieve something like Java's
synchronized methods.

Daniel
 
J

Jp Calderone

You could create a class that locks the mutex in the constructor and unlocks
it in the __del__ method.

class ScopedLock:
def __init__ (self, mutex):
self.mutex = mutex
mutex.acquire()

def __del__ (self):
self.mutex.release ()

use as
def do_something():
lock = ScopedLock (mutex)
# do something
# lock will be automatically released when returning


This works only in the current implementation of CPython where local
variables are usually (*) deleted when they fall out of scope.

Notably, this fails if an exception is raised, since the lock remains in
the locals dictionary of one of the frame objects in the traceback.
Definitely not desirable.

Jp
 
M

Michael Hudson

Ype Kingma said:
Some reasons:
- What should happen when an exception happens during the locked stuff?
- It is possible pass a reference to the lock during the locked stuff,
so although the lock goes out of local scope, there still might be
a reference to it.
- The moment that __del__() is called is not guaranteed.

You can also do it like this:

mutex = threading.Lock()
mutex.acquire()
try:
# now this stuff is locked
finally:
mutex.release() # explicit is better than implicit

This is the way to do it today. There's PEP 310 which, if accepted,
makes this at least shorter to write... (and PEP 310 references a
lengthy discussion about whether using __del__ like this is wise).

Cheers,
mwh
 
Y

Ype Kingma

Marco said:
This does not look nice to me. There should be something me easily.

An elegant and easier way has been designed, see PEP 310,
mentioned in another post in this thread:
http://www.python.org/peps/pep-0310.html

However, one normally does not use locks so often that the
lightly verbose idiom needed to use them becomes a problem.

Regards,
Ype
 
S

Sean R. Lynch

How about:

def lock_call(mutex, func, *args, **kwargs):
mutex.acquire()
try:
res = func(*args, **kwargs)
finally:
mutex.release()

return res

def do_something(blah):
# do stuff

m = threading.Lock
lock_call(m, do_something, "some data")
 
Y

Ype Kingma

Sean said:
How about:

def lock_call(mutex, func, *args, **kwargs):
mutex.acquire()
try:
res = func(*args, **kwargs)
finally:
mutex.release()

return res

Or even:

def lock_call(mutex, func, *args, **kwargs):
mutex.acquire()
try:
return func(*args, **kwargs)
finally:
mutex.release()

Regards,
Ype
 
M

Marco Bubke

Michael said:
This is the way to do it today. There's PEP 310 which, if accepted,
makes this at least shorter to write... (and PEP 310 references a
lengthy discussion about whether using __del__ like this is wise).

Thats looks really nice.

thx

Marco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,489
Latest member
BrigidaD91

Latest Threads

Top