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

CodePudding user response:

The
reference 3 floor Intel0011 response:
+ and a - are only one assembly code - & gt; This understanding is wrong, from the assembly point of view is three assembly code

This is the result of the disassembly
+
Mov ecx, [ebp + var_4]
The add ecx, 1
Mov [ebp + var_4], ecx

See when I'm debugging, this is the compiled, my assembly code is like this:
=> 0 x000000000040153d & lt; + 13 & gt; : mov DWORD PTR [RBP x4] 0, 0 x0
0 x0000000000401544 & lt; + 20 & gt; : add DWORD PTR [RBP x4] 0, 0 x1
The first is the initialization of 0, the second is a +

CodePudding user response:

Is the problem of thread synchronization?

CodePudding user response:




references 4 floor early play play nuclear response:
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

Words I see assembly code, only + this kind of operation is the lock, the generated assembly code is very much also, and a 1 or a==b this kind of operation without the lock, this is what circumstance?

CodePudding user response:

+, - not a atomic operations, unlocked there must be some problem, even if only one instruction, when two threads execute at the same time, also will be a competition problem

CodePudding user response:

 # include & lt; Iostream> 
# include & lt; Atomic>
# include & lt; Thread>
using namespace std;
Atomic_llong a {0};
Void func1 () {
for (int i=0; i <100000; I++) {
+ + a;
}
}
Void func2 () {
for (int i=0; i <100000; I++)
{
- a;
}
}
Int main ()
{
Thread the t1 (func1);
Thread t2 (func2);
T1. The join ();
T2. The join ();
cout }

CodePudding user response:

The
truth is right or wrong, 9/f, reference response:

Don't use of variable a + but instead USES a=a + 1, I think there is no lock in the assembly code, then it also has the function of the atomic operation? Isn't for the operation of the atomic variable should use atomic operation library?

CodePudding user response:

If multiple threads to write the same variable, certainly need to use the atomic operations, if read a write, usually don't need, unless the variable position across the cache line

CodePudding user response:

11 references, play big shoot early nuclear response: ,
if multi-threaded write a variable must need to use the atomic operations, if read a write, usually don't need, unless the variable position across the cache line

I said before is the atomic type, + the generated assembly code has a lock, but not a=1, and the generated assembly code a lot, which are very few, the key is I tried C11 atomic operation library to variable assignment, the generated assembly code has no lock, does this specification does not actually achieve the effect of the atom?

CodePudding user response:

reference 2 building self-confidence boy reply:
never synchronization, thread thread of execution body performed successively and the number is random, so either complete synchronization, or identify good execution of

I am in probing into the cause of the problem, rather than how to avoid this kind of problemnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related