Home > Back-end > Multi-threaded data security issues
Multi-threaded data security issues
Time:12-06
A is a global variable, the initial value of 0 Two threads loop execution { a++; A -; } The final result of non-zero Strangely, when + on the former, the result is always positive A - in the former, the result is always negative
+ and a - are only one assembly code Even if thread switches, + and a - number of execution should be constant, the last was supposed to return to zero!
And exchange caused by the + and - in the order of a strange phenomenon and how to explain? Value of modification is carried out directly in memory, without register
I can think of the reason for the time being, perform a -, data is not modified, has switched the thread and execute the +, and then in front of a void -
Which give a truth?
CodePudding user response:
Thread if I remember is performed at the same time, don't get the lock is the original variable values rather than change first and then get the value of the change
CodePudding user response:
Not well synchronized, thread thread of execution body performed successively and number is random, so either be synchronized, or determine the good execution order
CodePudding user response:
+ and a - are only one assembly code - & gt; This understanding is wrong, from the assembly point of view is three assembly code In fact examples of MOV EAX, [g_x]; Thread 1: Move 0 into a register. INC EAX. Thread 1: Increment the register to 1. [g_x] MOV EAX; Thread 1:1 Store back in g_x.
MOV EAX, [g_x]; Thread 2: Move 1 into a register. INC EAX. Thread 2: Increment the register to 2. [g_x] MOV EAX; Thread 2: Store 2 back in g_x. After both threads are done incrementing g_x, the value in g_x is 2. This is great and is exactly what we expect: take the zero (0), increment the it by 1 twice, and the answer is 2. Beautiful. But wait - Windows is a preemptive, multithreaded environment. So a thread can be switched away from the at any time and another thread took the continue executing the at any time. So the preceding code took not execute exactly as I 've written it home, it took the execute as follows:
MOV EAX, [g_x]; Thread 1: Move 0 into a register. INC EAX. Thread 1: Increment the register to 1.
MOV EAX, [g_x]; Thread 2: Move 0 into a register. INC EAX. Thread 2: Increment the register to 1. [g_x] MOV EAX; Thread 2: Store 1 back in g_x.
[g_x] MOV EAX; Thread 1:1 Store back in g_x. If the code executes this way, the final value in g_x is 1, not 2 as you expect! -- -- -- -- -- -- -- -- -- -- This is the result of the disassembly + Mov ecx, [ebp + var_4] The add ecx, 1 Mov [ebp + var_4], ecx
CodePudding user response:
To generate a few instructions depending on the compiler and compiler options (debug and release, such as optimization level), may also be: The add/sub/addr, 1 Or Inc/dec (addr) Such as Regardless of the compiler to generate a few instructions, in multiprocessor/multi-core systems is not atomic operation, this is the cause of dirty dirty read/write multithreaded, make sure to read/change/write atomization to use lock prefix + single instruction