473,657 Members | 2,566 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

atomic operations in presence of multithreading

I am wondering which operations in Python
are guaranteed to be atomic in the presence
of multi-threading. In particular, are assignment
and reading of a dictionary entry atomic?
For example, initially:
dictionary = {}
dictionary[key] = old_value
Then thread 1 does:
v = dictionary[key]
And thread 2 does:
dictionary[key] = new_value2
And thread 3 does:
dictionary[key] = new_value3
What I want to make sure of is that
thread 1 will read either the old_value
for key, or new_value2, or new_value3,
but not an intermediate value.
Which value in particular does not matter to me, as that
obviously depends on timing. I just want to make sure
that the dictionary internal data structures can't
become corrupted by multiple writers / readers.
Note: I realize that in this particular case
I can use locks to guarantee safety, but I am
wondering whether the basic language operations
such as dictionary reads and updates are guaranteed
to be atomic.
A related, more general question, is which
Python operations are atomic, and which are not.
I was unable to find this in the language reference,
but please direct me to the correct location
if I missed it.
Thanks,
Glenn
Jul 18 '05 #1
8 3571
Glenn Kasten wrote:
I am wondering which operations in Python
are guaranteed to be atomic in the presence
of multi-threading. In particular, are assignment
and reading of a dictionary entry atomic? [snip] I just want to make sure
that the dictionary internal data structures can't
become corrupted by multiple writers / readers. [snip] Python operations are atomic, and which are not.
I was unable to find this in the language reference,
but please direct me to the correct location
if I missed it.


It's probably not spelled out anywhere, but the "global interpreter
lock" entry and the Glossary and the first few paragraphs of section 8.1
of the documentation ("Thread State and the Global Interpreter Lock")
give you the gist of it.

Basically: multiple threads can't corrupt the interpreter's internals
(but a buggy C extension could).

-Dave
Jul 18 '05 #2
Dave Brueck wrote:
Glenn Kasten wrote:
I am wondering which operations in Python
are guaranteed to be atomic in the presence
of multi-threading. In particular, are assignment
and reading of a dictionary entry atomic?


[...]
Basically: multiple threads can't corrupt the interpreter's internals
(but a buggy C extension could).


The "dis" module can be helpful in analyzing such things, sometimes.
Realizing that the GIL ensures that individual bytecodes are
executed atomically ("boom!"), anything that shows up as a
separate bytecode instruction is basically thread-safe:
def func(): .... v = dictionary[key]
.... def func2(): .... dictionary[key] = new_value2
.... dis.dis(func) 2 0 LOAD_GLOBAL 0 (dictionary)
3 LOAD_GLOBAL 1 (key)
6 BINARY_SUBSCR
7 STORE_FAST 0 (v)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE dis.dis(func2)

2 0 LOAD_GLOBAL 0 (new_value2)
3 LOAD_GLOBAL 1 (dictionary)
6 LOAD_GLOBAL 2 (key)
9 STORE_SUBSCR
10 LOAD_CONST 0 (None)
13 RETURN_VALUE

The key instructions in the above are the dictionary lookup,
which is merely "BINARY_SUB SCR" in func(), and the dictionary
assignment, which is "STORE_SUBS CR" in func2(). If func
and func2 were in separate threads, either the lookup or
the store executes first, then the other, but they cannot
both be executing at the same time.

-Peter
Jul 18 '05 #3
Peter Hansen <pe***@engcorp. com> writes:
Dave Brueck wrote:
Glenn Kasten wrote:
I am wondering which operations in Python
are guaranteed to be atomic in the presence
of multi-threading. In particular, are assignment
and reading of a dictionary entry atomic?
> [...]
Basically: multiple threads can't corrupt the interpreter's
internals (but a buggy C extension could).


[...]
The key instructions in the above are the dictionary lookup,
which is merely "BINARY_SUB SCR" in func(), and the dictionary
assignment, which is "STORE_SUBS CR" in func2(). If func
and func2 were in separate threads, either the lookup or
the store executes first, then the other, but they cannot
both be executing at the same time.


As was pointed out to me when this came up recently, it is possible
for callbacks into python to screw this simple picture up a little.

The obvious case is a user-defined class with a __setitem__ method. In
this case, STORE_SUBSCR calls arbitrary Python code, and so can be
interrupted by a thread switch.

Given that the original question was about dictionaries, which are
coded in C (and so not subject to this issue) there is still the
following case: when the old value stored in the dictionary is
replaced, that could be the last reference to it. When the old value
is freed, its __del__ method gets called - arbitrary Python code
again.

But the basic idea is sound. The interpreter releases the GIL *only*
between Python bytecodes. As long as you cater for recursive cases
like the above (and obvious ones like CALL_METHOD), you're OK.

Finally, C code has the option of explicitly releasing the GIL -
"long-running" operations like file reads do this, but basic ops
don't.

Paul.
--
This signature intentionally left blank
Jul 18 '05 #4
Paul Moore wrote:
Peter Hansen <pe***@engcorp. com> writes:

Dave Brueck wrote:

Glenn Kasten wrote:
I am wondering which operations in Python
are guaranteed to be atomic in the presence
of multi-threading. In particular, are assignment
and reading of a dictionary entry atomic?

> [...]

Basically: multiple threads can't corrupt the interpreter's
internals (but a buggy C extension could).


[...]

The key instructions in the above are the dictionary lookup,
which is merely "BINARY_SUB SCR" in func(), and the dictionary
assignment, which is "STORE_SUBS CR" in func2(). If func
and func2 were in separate threads, either the lookup or
the store executes first, then the other, but they cannot
both be executing at the same time.

As was pointed out to me when this came up recently, it is possible
for callbacks into python to screw this simple picture up a little.

The obvious case is a user-defined class with a __setitem__ method. In
this case, STORE_SUBSCR calls arbitrary Python code, and so can be
interrupted by a thread switch.

Given that the original question was about dictionaries, which are
coded in C (and so not subject to this issue) there is still the
following case: when the old value stored in the dictionary is
replaced, that could be the last reference to it. When the old value
is freed, its __del__ method gets called - arbitrary Python code
again.

But the basic idea is sound. The interpreter releases the GIL *only*
between Python bytecodes. As long as you cater for recursive cases
like the above (and obvious ones like CALL_METHOD), you're OK.


Yep, though I think the OP was mostly concerned with Python's internals
gettin messed up by unlocked multithreaded access, so he doesn't have to
be concerned about the above.

-Dave
Jul 18 '05 #5
Paul Moore <pf******@yahoo .co.uk> wrote in news:y8******** **@yahoo.co.uk:
Given that the original question was about dictionaries, which are
coded in C (and so not subject to this issue) there is still the
following case: when the old value stored in the dictionary is
replaced, that could be the last reference to it. When the old value
is freed, its __del__ method gets called - arbitrary Python code
again.


Right, but the new value has already been stored in the dictionary at the
point where the __del__ method is called, so as far as the OP is concerned
this is still safe.
Jul 18 '05 #6
Duncan Booth wrote:
Paul Moore <pf******@yahoo .co.uk> wrote in news:y8******** **@yahoo.co.uk:
Given that the original question was about dictionaries, which are
coded in C (and so not subject to this issue) there is still the
following case: when the old value stored in the dictionary is
replaced, that could be the last reference to it. When the old value
is freed, its __del__ method gets called - arbitrary Python code
again.


Right, but the new value has already been stored in the dictionary at the
point where the __del__ method is called, so as far as the OP is concerned
this is still safe.


For some definition of "safe", perhaps. It won't corrupt any Python
internals, but if the __del__() method has side effects that the
threaded code is relying on, it may give unexpected results. (One might
want to rely on the fact that, once an object holding a socket is
removed from a dictionary, that socket will be closed; if that close
happens in the object's __del__(), then there's no guarantee that it
*will* actually be closed before a thread switch occurs. (Relying on
__del__() is hazardous in any case, actually, thanks to differing GC
between different implementations of Python, but it's even worse in a
threaded environment.))

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #7
Dave Brueck <da**@pythonapo crypha.com> writes:
Yep, though I think the OP was mostly concerned with Python's
internals gettin messed up by unlocked multithreaded access, so he
doesn't have to be concerned about the above.


I don't think that Python's internals can *ever* be messed up by
unlocked multithreaded access - that's what the GIL is for.

Paul.
--
This signature intentionally left blank
Jul 18 '05 #8
Paul Moore wrote:
Dave Brueck <da**@pythonapo crypha.com> writes:

Yep, though I think the OP was mostly concerned with Python's
internals gettin messed up by unlocked multithreaded access, so he
doesn't have to be concerned about the above.

I don't think that Python's internals can *ever* be messed up by
unlocked multithreaded access - that's what the GIL is for.


Yeah, that was mentioned earlier:

"multiple threads can't corrupt the interpreter's internals (but a buggy
C extension could)."

-Dave
Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5272
by: Paul Moore | last post by:
I can't find anything which spells this out in the manuals. I guess that, at some level, the answer is "a single bytecode operation", but I'm not sure that explains it for me. This thought was triggered by a comment on the Python Cookbook site, which basically said that it was OK to do tss = {} ... id = thread.get_ident() tss = {}
42
3340
by: Shayan | last post by:
Is there a boolean flag that can be set atomically without needing to wrap it in a mutex? This flag will be checked constantly by multiple threads so I don't really want to deal with the overhead of mutexes or semaphores. Thanks. Shayan
7
2158
by: dm | last post by:
Hi, I'd like to know if the C standard can guarantee that an assignment to/from a variable will be atomic, that is will occur in a single indivisible instruction. For example, if I have the following code: int global_var;
28
7372
by: robert | last post by:
In very rare cases a program crashes (hard to reproduce) : * several threads work on an object tree with dict's etc. in it. Items are added, deleted, iteration over .keys() ... ). The threads are "good" in such terms, that this core data structure is changed only by atomic operations, so that the data structure is always consistent regarding the application. Only the change-operations on the dicts and lists itself seem to cause problems...
6
6245
by: blackstreetcat | last post by:
consider this code : int i; //gobal var Thread1: i=some value; Thread2: if (i==2) dosomething(); else dosomethingelse();
9
15053
by: Dave Stallard | last post by:
Pardon if this is the wrong newsgroup for this question, and/or if this question is naive. I have a multi-threaded Windows application in which certain variables/object fields are shared: one thread may write the variable, and the other thread read it. The variables in question may have int or int* types. Question: Is it safe to do this? Or is it possible a read that happens at the same time as a write may retrieve a scrambled value,...
11
2063
by: japhy | last post by:
Is there a way to read a line (a series of characters ending in a newline) from a file (either by descriptor or stream) atomically, without buffering additional contents of the file?
2
2932
by: Freedom fighter | last post by:
Hello, Is a singleton class the same as an atomic class? I know that a singleton class can only be instantiated once, but does that concept apply to an atomic class? Thank you.
11
6325
by: Jon Harrop | last post by:
Can read locks on a data structure be removed safely when updates are limited to replacing a reference? In other words, is setting a reference an atomic operation? I have been assuming that all writes of <=1 word of data are atomic. Is this actually documented anywhere? -- Dr Jon D Harrop, Flying Frog Consultancy http://www.ffconsultancy.com/products/?u
0
8392
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8825
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8732
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7324
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6163
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4151
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4302
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1611
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.