Minimalistic Software Transactional Memory

Fuzzyman fuzzyman at gmail.com
Sat Dec 8 18:55:46 EST 2007


On Dec 8, 10:53 pm, Michael Sparks <m... at cerenity.org> wrote:
> Hi,
>
> I'm interested in writing a simple, minimalistic, non persistent (at this
> stage) software transactional memory (STM) module. The idea being it should
> be possible to write such a beast in a way that can be made threadsafe fair
> easily.
>
> For those who don't know, STM is a really fancy way of saying variables
> with version control (as far as I can tell :-) designed to enable threadsafe
> shared data.
>
> I'm starting with the caveat here that the following code is almost
> certainly not threadsafe (not put any real thought into that as yet),
> and I'm interested in any feedback on the following:
>
>    * Does the API look simple enough?
>    * Are there any glaring mistakes in the code ? (It's always harder to see
>      your own bugs)
>    * What key areas appear least threadsafe, and any general suggestions
>      around that.
>
> If I get no feedback I hope this is of interest. Since these things get
> archived, if you're reading this a month, 6 months, a year or more from
> now, I'll still be interested in feedback...
>
> OK, API.
>
> First of all we need to initialise the store:
>
>     S = Store()
>
> We then want to get a value from the store such that we can use the value,
> and do stuff with it:
>
>     greeting = S.using("hello")
>
> Access the value:
>
>     print repr(greeting.value)
>
> Update the value:
>
>     greeting.set("Hello World")
>
> Commit the value back to the store:
>
>     greeting.commit()
>
> If you have concurrent updates of the same value, the following exception
> gets thrown:
>     ConcurrentUpdate
>
> cf:
>     >>> S = Store()
>     >>> greeting = S.using("hello")
>     >>> par = S.using("hello")
>     >>> greeting.set("Hello World")
>     >>> par.set("Woo")
>     >>> greeting.commit()
>     >>> par.commit()
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>       File "<stdin>", line 12, in commit
>       File "<stdin>", line 11, in set
>     __main__.ConcurrentUpdate
>
> That's pretty much the simplest API I can come up with. (I've tried a few
> others but didn't really like them)
>
> The way this works is we have a Store that manages Values. (perhaps a better
> name may be variables to avoid clashing with pythons parlance of labels and
> values?)
>
> Anyhow, you can ask the store for Value, which it will give you. The Value
> knows what it's called and where it's from, so when you tell it to commit,
> it can try to do so. The little detail here is you get a /copy/ of the
> Value not the stored Value. (This is to avoid accidental concurrent update
> of the same actual object)
>

Wouldn't it be more useful having a store (possibly with a mapping
API?) that stored several values. Then a single commit can be done at
the end of the transaction.

If the transaction fails, then the whole process can be repeated with
none of the changes having been committed.

The tricky part is that other threads asking for the value should get
the *old* value until the commit has been done - so you need to know
which thread 'value' is being asked for from.

Michael



More information about the Python-list mailing list