[pypy-dev] How will STM actually integrate with normal Python code
Armin Rigo
arigo at tunes.org
Tue Jan 31 17:58:53 CET 2012
Hi Timothy,
On Tue, Jan 31, 2012 at 16:26, Timothy Baldridge <tbaldridge at gmail.com> wrote:
> def foo(d):
> if "foo" in d:
> del d["foo"]
>
> Will never cause a segmentation fault (due to multiple threads
> accessing "d" at the same time), but it may throw a KeyError. That is,
> all Python code will continue to be "thread-safe" as it is in CPython,
> but race conditions will continue to exist and must be handled in
> standard ways (locks, CAS, etc.).
No, precisely not. Such code will continue to work as it is, without
race conditions or any of the messy multithread-induced headaches.
Locks, CAS, etc. are all superflous.
So what would work and not work? In one word: all "transactions" work
exactly as if run serially, one after another. A transaction is just
one unit of work; a callback. We use this working code for comparison
on top of CPython or a non-STM PyPy:
https://bitbucket.org/pypy/pypy/raw/stm/lib_pypy/transaction.py . You
add transactions with the add() function, and execute them all with
the run() function (which typically contains further add()s). The
only source of non-determinism is in run() taking a random transaction
as the next one. Of course this demo code runs the transactions
serially, but the point is that even "pypy-stm" gives you the illusion
of running them serially.
So you stat by writing code that is *safe*, and then you have to think
a bit in order to increase the parallelism, instead of the other way
around when using traditional multithreading in non-Python languages.
There are rules that are a bit subtle (but not too much) about when
transactions can parallelize or not. Basically, as soon as a
transaction does I/O, all the other transactions will be stalled; and
if transactions very often change the same objects, then you will get
a lot of conflicts and restarts.
> "In PyPy, we look at STM like we would look at the GC. It may be
> replaced in a week by a different one, but for the "end user" writing
> pure Python code, it essentially doesn't make a difference. "
I meant to say that STM, in our case, is just (hopefully) an
optimization that lets some programs run on multiple CPUs --- the ones
that are based on the 'transaction' module. But it's still just an
optimization in the sense that the programs run exactly as if using
the transaction.py I described above.
In yet other words: notice that transaction.py doesn't even use the
'thread' module. So if we get the same behavior with pypy-stm's
built-in 'transaction' module, it means that the example you described
is perfectly safe as it is.
(Update: today we have a "pypy-stm" that works exactly like
transaction.py and exhibits multiple-CPU usage. It's just terribly
slow and doesn't free any memory ever :-) But it runs
http://paste.pocoo.org/show/543646/ , which is a simple epoll-based
server creating new transactions in order to do the CPU-intensive
portions of answering the requests. In the code there is no trace of
CAS, locks, 'multiprocessing', etc.)
A bientôt,
Armin.
More information about the pypy-dev
mailing list