about concurrency (again)
- From: "michele.simionato@xxxxxxxxx" <michele.simionato@xxxxxxxxx>
- Date: Sun, 18 Nov 2007 22:32:50 -0800 (PST)
I have been reading the recent thread about concurrency, which is
unfortunately
for the most part over my head, and I wanted to assess what I
understand
of concurrency (or I think I understand).
In particular I wanted to make clear what do you mean for message
passing
and what is the name for the model I have in mind, since I actually
lack a formal
training on concurrency. I will make a very simple example to make
things
crystal clear; please forgive me if I am too pedagogical.
Suppose I am testing a software for launching nuclear missiles (this
is
just to make things a bit more melodramatic;). I will have routines
like the following (let me use Python, since I am more confortable
with it):
safe_mode = True
def enable_safe_mode():
global safe_mode
safe_mode = True
def disable_safe_mode():
global safe_mode
safe_mode = False
def launch_nuclear_warhead():
if safe_mode:
print 'Just emulating the launch of a nuclear warhead'
else:
print 'You just launched a nuclear warhead!'
def test_launch():
enable_safe_mode()
launch_nuclear_warhead()
When I call test_launch, nothing bad happens, since I have enabled the
safe_mode flag and I feel confident that my code has no bugs.
Suppose now that a collegue of mine is doing tests with the safe_mode
setting routines:
def test_safe_mode():
try:
disable_safe_mode()
finally:
enable_safe_mode()
Notice that my collegue is very careful to re-enable the safe mode
after he
tested disable_safe_mode, so he is also confident that his code has no
bugs.
Both routines are actually correct for non-concurrent code, but they
are buggy in presence of concurrency. Actually if both test_launch
and test_safe_mode run simultaneously the following scenario may
happen,
in a non-deterministic way:
1. in test_launch enable_safe_mode is called;
2. in test_safe_mode disable_safe_mode is called;
3. in test_launch launch_nuclear_warhead is called;
4. the warhead is fired!
5. in test_safe_mode enable_safe_mode is called, but too late :-(
How do we avoid firing the missile? The usual solution is to put locks
everywhere but it is clearly too invasive. What I would do (and I
would
like to know how this approach is called in the literature) is to
introduce
a message_manager object which dispatches to the right routines and
takes care of the locks in a centralized way. One possible
implementation
could be the following:
def message_manager():
while True:
with threading.Lock():
message = yield
message()
# "instantiate" the manager in the main thread
manager = message_manager()
manager.next()
# send messages like manager.send(test_launch)
Now different threads can send to the manager a message (the message
is the routine the manager should call) and be assured that the
messages will be processed sequentially. Basically the manager is
converting back the critical parts of the application to single-
threaded
mode. The same discussion clearly applies to independent process,
where
the safe_mode flag could be stored in a file or in a database and
the lock could be a file lock or a transactional lock.
How would you improve over this solution and what would you
recommend?
Concrete examples are welcome!
Michele Simionato
.
- Follow-Ups:
- Re: about concurrency (again)
- From: David B. Benson
- Re: about concurrency (again)
- Prev by Date: Re: A really basic question about category theory
- Next by Date: Re: Concurency in the functional world
- Previous by thread: A really basic question about category theory
- Next by thread: Re: about concurrency (again)
- Index(es):
Relevant Pages
|