4 ms·
That's a logical race, not a data race, right? Technically, "counter = counter + 1" accesses counter twice (once to read and once to write). The fact that "cou
by jasonhansel 5y ago
That's a logical race, not a data race, right? Technically, "counter = counter + 1" accesses counter twice (once to read and once to write).
The fact that "counter" gets modified between the read and the write doesn't imply that multiple accesses were happening simultaneously; it just means that accesses from different threads were getting interleaved. The GIL would only prevent the former but not the latter, since a thread can give up the GIL at any point between operations.
- chrisseaton 5y agoThe semantic operation is increment. It being read, add, write is an implementation detail. The increments happen simultaneously, meeting the definition for 'data race' according to Padua, which is the definition most people would use. https://link.springer.com/referenceworkentry/10.1007/978-0-387-09766-4_36 https://link.springer.com/referenceworkentry/10.1007/978-0-3...
- Thorrez 5y ago>The semantic operation is increment. Why? Who defines that?
- chrisseaton 5y agoBecause that's what the user wrote. You can reason about the operation in terms of smaller operations (such as read, add, store) but not more coarse operations, because the user could have just written the single operation.
- Thorrez 5y agoConsider the situation "counter = counter + get_value()". That also can be reasoned about in terms of smaller operations, but not more coarse operations, because the user could have just written the single operation. We wouldn't expect this to be atomic, because the get_value() function could do tons of things, and we don't expect all that to be atomic. It doesn't make sense to call something atomic just because the user wrote it.
- Kranar 5y agoYour link doesn't say anything about data races, it's a link to race conditions which are not the same thing as data races.
- chrisseaton 5y ago> Your link doesn't say anything about data races Under the section 'General Races and Data Races', then 'Data race'. There's a definition of data races, in relation to general races. "A data race is a special case of a general race. A data race exists between conflicting memory accesses..."
- rkeene2 5y agoThe two semantic operations are increment then store.
- deleted 5y ago[deleted]
- chrisseaton 5y agoThat's an implementation detail based on a particular architecture. A different architecture could have an atomic increment operation if it wanted to, and Python could use it for this syntax.
- squeaky-clean 5y agoIn Python though, there's really only one architecture. Yes there's PyPy and such, but CPython and it's bytecode is both the official implementation and official spec of Python. Maybe the underlying hardware has those operations, but the Python VM does not.
- a-dub 5y agoit's kind of the canonical example of a data race. down in machine code land, the instructions that implement synchronization primitives are typically of the form "check prior existing value and change the value in one atomic step." and yes, as everyone is saying, the gil keeps the python interpreter/runtime from ending up in an inconsistent state... its behavior should not be depended on by user programs. if you need to increment a counter, use a lock, or a counter that explicitly states that it's a thread safe atomic counter on the tin.