I. Analysis of the phenomenon of the previous procedure
Let's start with the last program in the previous article.
#include <stdio.h>#include <windows.h>Const unsigned intThread_num =Ten;D word WINAPI threadfunc (LPVOID);intMain () {printf ("I am the main thread, PID =%d\n", GetCurrentThreadID ());//Output main path PIDHANDLE Hthread[thread_num]; for(inti =0; i < Thread_num; i++) {Hthread[i] = CreateThread (NULL,0, ThreadFunc, &i,0, NULL);//Create thread} waitformultipleobjects (Thread_num,hthread,true, INFINITE);//Wait until all child threads are returned . return 0;} DWORD WINAPI ThreadFunc (LPVOID p) {intn = * (int*) p; Sleep ( +*N);//Nth thread sleeps n secondsprintf"I am, pid =%dthe child Threads\ n", GetCurrentThreadID ());//Output sub-thread PIDprintf"pid =%dthe child thread exits\ n", GetCurrentThreadID ());//Delay 10s after output return 0;}
Look at the output of the program:
According to the normal situation should be each row output two columns, but in the middle of a row more out of a column, look at the circle in the picture, PID = 208 thread output thread PID and did not immediately exit, but wait until the last exit. (It may not be the same for each run, this is only the case), which is why. This involves the thread scheduling problem, stating that the PID = 208 thread output thread PID after the operating system thread scheduling, the CPU resources are preempted by other threads, the thread until the last redistribution to the CPU resources, re-execution.
Second, atomic operation
This is obviously to write atomic operations, but so far, there is no place to mention what is atomic operation, do not worry, then slowly. So what is atomic manipulation? an operation that, if it can be done without interruption, is called an atomic operation.
Let's see the program.
#include <stdio.h>#include <windows.h>Const unsigned intThread_num = -;unsigned intG_count =0;D word WINAPI threadfunc (LPVOID);intMain () {HANDLE hthread[thread_num]; for(inti =0; i < Thread_num; i++) {Hthread[i] = CreateThread (NULL,0, ThreadFunc,0,0, NULL);//Create thread} waitformultipleobjects (Thread_num, Hthread,true, INFINITE);//Wait until all child threads are returnedprintf"Total%da thread adds one to the value of G_count, and now G_count =%d\n", Thread_num, G_count);return 0;} DWORD WINAPI ThreadFunc (LPVOID p) {Sleep ( -); g_count++; Sleep ( -);return 0;}
There is a global variable g_count, and each thread adds one to this global variable, so let's look at the final output of 50, and we'll look at the output of the program (which may be different each time)
Why is this so??? Obviously have 50 threads all give g_count add one, why output 46, root is g_count++; On this statement, there is only one C + + statement, it should be said that there should be no problem, but it is, now, here lay a breakpoint, start debugging, open the Disassembly window (vs compiler shortcut key alt+8), such as
Can see, this a C + + statement, is divided into three assembly statements, first put the value of G_count to register eax, and then register EAX value plus one, and then eax value to G_count, so that the completion of a g_count++ operation. The reason for the problem is that during the execution of these assembly statements, a thread switch is sent, for example, a thread has just finished executing add eax,1 has not given the value of EAX to G_count, then the B thread began to execute, g_count the original value was deposited eax, which modifies the EAX The value that is calculated in a thread.
Therefore, when reading and writing a variable in a multithreaded environment, we need a way to ensure that the increment operation on a value is atomic-that is, the operation cannot be interrupted, and when a thread performs an atomic operation, the other thread must wait for it to complete before it can begin executing the atomic operation. The Windows system provides us with some functions that begin with interlocked to accomplish this task. Here is just the concept of atomic operation, which is closely related to thread synchronization, but these to start with the function of the interlocked we do not have to introduce each one, interested can understand their own.
Windows Multithreading (three) atomic operations