<p>I have two threads, one updating an int and one reading it. This is a statistic value where the order of the reads and writes is irrelevant.</p>

<p>My question is, do I need to synchronize access to this multi-byte value anyway?  Or, put another way, can part of the write be complete and get interrupted, and then the read happen.</p>

<p>For example, think of a value = 0x0000FFFF that gets incremented value of 0x00010000.</p>

<p>Is there a time where the value looks like 0x0001FFFF that I should be worried about?  Certainly the larger the type, the more possible something like this to happen.</p>

<p>I've always synchronized these types of accesses, but was curious what the community thinks.</p>

[{'answer_id': 54196, 'author': 'Leon Timmermans', 'author_id': 4727, 'author_profile': 'https://Stackoverflow.com/users/4727', 'pm_score': 0, 'selected': False, 'text': '<p>No, they aren\'t (or at least you can\'t assume they are). Having said that, there are some tricks to do this atomically, but they typically aren\'t portable (see <a href="http://en.wikipedia.org/wiki/Compare-and-swap" rel="nofollow noreferrer">Compare-and-swap</a>).</p>\n'}, {'answer_id': 54201, 'author': 'Anthony Williams', 'author_id': 5597, 'author_profile': 'https://Stackoverflow.com/users/5597', 'pm_score': 3, 'selected': False, 'text': "<p>Yes, you need to synchronize accesses. In C++0x it will be a data race, and undefined behaviour. With POSIX threads it's already undefined behaviour.</p>\n\n<p>In practice, you might get bad values if the data type is larger than the native word size. Also, another thread might never see the value written due to optimizations moving the read and/or write.</p>\n"}, {'answer_id': 54224, 'author': 'Jason Cohen', 'author_id': 4926, 'author_profile': 'https://Stackoverflow.com/users/4926', 'pm_score': 2, 'selected': False, 'text': '<p>You must synchronize, but on certain architectures there are efficient ways to do it.</p>\n\n<p>Best is to use subroutines (perhaps masked behind macros) so that you can conditionally replace implementations with platform-specific ones.</p>\n\n<p>The Linux kernel already has some of this code.</p>\n'}, {'answer_id': 54236, 'author': 'gabr', 'author_id': 4997, 'author_profile': 'https://Stackoverflow.com/users/4997', 'pm_score': 4, 'selected': False, 'text': "<p>IF you're reading/writing 4-byte value AND it is DWORD-aligned in memory AND you're running on the I32 architecture, THEN reads and writes are atomic.</p>\n"}, {'answer_id': 54242, 'author': 'Skizz', 'author_id': 1898, 'author_profile': 'https://Stackoverflow.com/users/1898', 'pm_score': 6, 'selected': False, 'text': "<p>Boy, what a question. The answer to which is:</p>\n\n<blockquote>\n  <p>Yes, no, hmmm, well, it depends</p>\n</blockquote>\n\n<p>It all comes down to the architecture of the system. On an IA32 a correctly aligned address will be an atomic operation. Unaligned writes might be atomic, it depends on the caching system in use. If the memory lies within a single L1 cache line then it is atomic, otherwise it's not. The width of the bus between the CPU and RAM can affect the atomic nature: a correctly aligned 16bit write on an 8086 was atomic whereas the same write on an 8088 wasn't because the 8088 only had an 8 bit bus whereas the 8086 had a 16 bit bus.</p>\n\n<p>Also, if you're using C/C++ don't forget to mark the shared value as volatile, otherwise the optimiser will think the variable is never updated in one of your threads.</p>\n"}, {'answer_id': 54294, 'author': 'kenny', 'author_id': 3225, 'author_profile': 'https://Stackoverflow.com/users/3225', 'pm_score': 0, 'selected': False, 'text': '<p>I agree with many and especially <a href="https://stackoverflow.com/questions/54188/are-c-reads-and-writes-of-an-int-atomic#54224">Jason</a>. On windows, one would likely use InterlockedAdd and its friends.</p>\n'}, {'answer_id': 54444, 'author': 'Adam Mitz', 'author_id': 2574, 'author_profile': 'https://Stackoverflow.com/users/2574', 'pm_score': 7, 'selected': True, 'text': '<p>At first one might think that reads and writes of the native machine size are atomic but there are a number of issues to deal with including cache coherency between processors/cores.  Use atomic operations like Interlocked* on Windows and the equivalent on Linux.  C++0x will have an "atomic" template to wrap these in a nice and cross-platform interface.  For now if you are using a platform abstraction layer it may provide these functions.  <a href="http://www.cse.wustl.edu/~schmidt/ACE.html" rel="noreferrer">ACE</a> does, see the class template <a href="http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/ACE/ace/Atomic_Op.inl" rel="noreferrer">ACE_Atomic_Op</a>.</p>\n'}, {'answer_id': 56998, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': '<p>To echo what everyone said upstairs, the language pre-C++0x cannot guarantee anything about shared memory access from multiple threads. Any guarantees would be up to the compiler.</p>\n'}, {'answer_id': 58064, 'author': 'JeffV', 'author_id': 445087, 'author_profile': 'https://Stackoverflow.com/users/445087', 'pm_score': 0, 'selected': False, 'text': '<p>Asside from the cache issue mentioned above...</p>\n\n<p>If you port the code to a processor with a smaller register size it will not be atomic anymore.</p>\n\n<p>IMO, threading issues are too thorny to risk it.</p>\n'}, {'answer_id': 77498, 'author': 'Andrew Stein', 'author_id': 13029, 'author_profile': 'https://Stackoverflow.com/users/13029', 'pm_score': 2, 'selected': False, 'text': '<p>On Windows, Interlocked***Exchange***Add is guaranteed to be atomic. </p>\n'}, {'answer_id': 2796328, 'author': 'Edward Howorka', 'author_id': 336468, 'author_profile': 'https://Stackoverflow.com/users/336468', 'pm_score': -1, 'selected': False, 'text': '<p>The only portable way is to use the sig_atomic_t type defined in signal.h header for your compiler.  In most C and C++ implementations, that is an int.  Then declare your variable as "volatile sig_atomic_t."</p>\n'}, {'answer_id': 3378960, 'author': 'siddhusingh', 'author_id': 306819, 'author_profile': 'https://Stackoverflow.com/users/306819', 'pm_score': 0, 'selected': False, 'text': "<p>Lets take this example </p>\n\n<pre><code>int x;\nx++;\nx=x+5;\n</code></pre>\n\n<p>The first statement is assumed to be atomic because it translates to a single INC assembly directive that takes a single CPU cycle. However, the second assignment requires several operations so it's clearly not an atomic operation.</p>\n\n<p>Another e.g,</p>\n\n<pre><code>x=5;\n</code></pre>\n\n<p>Again, you have to disassemble the code to see what exactly happens here.</p>\n"}, {'answer_id': 3520345, 'author': 'siddhusingh', 'author_id': 306819, 'author_profile': 'https://Stackoverflow.com/users/306819', 'pm_score': 0, 'selected': False, 'text': "<p>tc,\nI think the moment you use a constant ( like 6) , the instruction wouldn't be completed in one machine cycle.\nTry to see the instruction set of x+=6 as compared to x++</p>\n"}, {'answer_id': 9903090, 'author': 'etham', 'author_id': 806286, 'author_profile': 'https://Stackoverflow.com/users/806286', 'pm_score': 0, 'selected': False, 'text': "<p>Some people think that ++c is atomic, but have a eye on the assembly generated. For example with 'gcc -S' :</p>\n\n<pre><code>movl    cpt.1586(%rip), %eax\naddl    $1, %eax\nmovl    %eax, cpt.1586(%rip)\n</code></pre>\n\n<p>To increment an int, the compiler first load it into a register, and stores it back into the memory. This is not atomic.</p>\n"}, {'answer_id': 19513666, 'author': 'Jean Davy', 'author_id': 888576, 'author_profile': 'https://Stackoverflow.com/users/888576', 'pm_score': 0, 'selected': False, 'text': '<p>Definitively NO !\nThat answer from our highest C++ authority, M. Boost:<br>\n<strong><a href="http://www.boost.org/doc/libs/1_54_0/doc/html/atomic.html#atomic.introduction.introduction_purpose" rel="nofollow">Operations on "ordinary" variables are not guaranteed to be atomic.</a></strong></p>\n'}, {'answer_id': 67762089, 'author': 'coredump', 'author_id': 5227845, 'author_profile': 'https://Stackoverflow.com/users/5227845', 'pm_score': -1, 'selected': False, 'text': "<p>Reads and writes are atomic, but you also need to worry about the compiler re-ordering your code. Compiler optimizations may violate happens-before relationship of statements in your code. By using atomic you don't have to worry about that.\n...\natomic i;</p>\n<p>soap_status = GOT_RESPONSE ;\ni = 1</p>\n<p>In the above example, the variable 'i' will only be set to 1 after we get a soap response.</p>\n"}]
['https://Stackoverflow.com/questions/54188', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2167252/']