77 lines
2.3 KiB
Plaintext
77 lines
2.3 KiB
Plaintext
From: gmcm at hypernet.com (Gordon McMillan)
|
|
Date: Tue, 13 Apr 1999 22:10:51 GMT
|
|
Subject: threads
|
|
In-Reply-To: <80BFA4D02E598C65.76C7CFE2D53BC9F1.ECCA6CF6DE46FB03@library-proxy.airnews.net>
|
|
References: <80BFA4D02E598C65.76C7CFE2D53BC9F1.ECCA6CF6DE46FB03@library-proxy.airnews.net>
|
|
Message-ID: <1288080841-20523503@hypernet.com>
|
|
Content-Length: 1950
|
|
X-UID: 1384
|
|
|
|
Eric Lee Green wonders about Python threads:
|
|
|
|
> My question is this: How "atomic" are basic Python variable
|
|
> operations?
|
|
|
|
This exact question was asked not long ago. My reply, and Guido's
|
|
clarifications follow:
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
Gordon McMillan replies:
|
|
|
|
> In general, Python will switch between threads every N (10, unless
|
|
> you've rebuilt with another constant) byte code instructions. Any
|
|
> byte-code instruction is therefore atomic.
|
|
>
|
|
> > For examples:
|
|
> >
|
|
> > Can I safely create/update a global variable from a thread or do I
|
|
> > risk breaking any dictionary implementation stuff (pointers/hash
|
|
> > table slots etc)? [Empirical evidence suugests this is OK].
|
|
>
|
|
> Dictionaries are dandy. Updating a single global is fine.
|
|
>
|
|
> > Can I append to a list without various pointers getting messed up?
|
|
> > [Prolly not, huh? Otherwise we wouldn't need the queue module ..
|
|
> > or is this just a hangover from earlier days?]
|
|
>
|
|
> Lists are trickier. Individual operations are atomic, but most of
|
|
> the time, doing something with a list takes more than one op. You're
|
|
> normally dealing with the list and an index, so you're better off
|
|
> protecting the list. That is, you can "safely" append, but even that
|
|
> may screw up someone else who is iterating.
|
|
|
|
Some examples will clarify also.
|
|
|
|
These are atomic (L, L1, L2 are lists, D, D1, D2 are dicts, x, y
|
|
are objects, i, j are ints):
|
|
|
|
L.append(x)
|
|
L1.extend(L2)
|
|
L1[i:j] = L2
|
|
x = y
|
|
x.field = y
|
|
D[x] = y
|
|
D1.update(D2)
|
|
|
|
These aren't:
|
|
|
|
i = i+1
|
|
L.append(L[-1])
|
|
L[i] = L[j]
|
|
D[x] = D[x] + 1
|
|
|
|
Note: operations that replace other objects may invoke those other
|
|
objects' __del__ method when their reference count reaches zero, and
|
|
that can affect things. This is especially true for the mass updates
|
|
to dictionaries and lists.
|
|
|
|
--Guido van Rossum (home page: http://www.python.org/~guido/)
|
|
|
|
|
|
- Gordon
|
|
|
|
|
|
|
|
|