[OS] multithreading-atomic operation Interlocked series functions

Source: Internet
Author: User
Tags volatile

Transferred from: http://blog.csdn.net/morewindows/article/details/7429155

On a "multi-threading-the first intimate contact CreateThread and _beginthreadex Essential difference" mentioned a multi-threaded count Function. To describe the convenience and the code brevity, we can only output the last count of the results to see if the program is running in Error. It's also very similar to how many users log in on a website per day, each user logging in with a thread emulation, and the thread running will increment a variable that represents a Count. The value of the last output count of the program indicates how many users are logged in today, and if this value is not equal to the number of threads we started, it clearly indicates that the program is PROBLEMATIC. The entire program code is as Follows:

1#include <stdio.h>2#include <process.h>3#include <windows.h>4 volatile Longg_nlogincount;//Number of Logins5Unsignedint__stdcall Fun (void*ppm);//Thread Functions6 Const intThread_num =Ten;//Number of startup threads7Unsignedint__stdcall Threadfun (void*PPM)8 {9Sleep ( -);//some work shouldTeng_nlogincount++; oneSleep ( -); a     return 0; - } - intMain () the { -G_nlogincount =0; -  - HANDLE handle[thread_num]; +      for(inti =0; I < thread_num; i++) -handle[i] = (handle) _beginthreadex (NULL,0, threadfun, NULL,0, NULL); +  a waitformultipleobjects (thread_num, handle, TRUE, INFINITE); atprintf"there are%d users logged in after logging the result is%d\n", thread_num, g_nlogincount); -     return 0; -}

The program simulates 10 user logins and runs the following results:

As with the previous Thread-count program, the output of the program seems to have no problem. Below we add a few users to try, now simulate 50 users login, in order to facilitate the observation of the results, in the program will be 10 user logon process repeated 20 times, the code is as Follows:

1#include <stdio.h>2#include <process.h>3#include <windows.h>4 volatile Longg_nlogincount;//Number of Logins5Unsignedint__stdcall Fun (void*ppm);//Thread Functions6 Const intThread_num = 50;//Number of startup threads7Unsignedint__stdcall Threadfun (void*PPM)8 {9Sleep ( -);//some work shouldTeng_nlogincount++; oneSleep ( -); a     return 0; - } - intMain () the { -     intnum = -; -      while(num--) -     { +G_nlogincount =0; -  + HANDLE handle[thread_num]; a          for(inti =0; I < thread_num; i++) athandle[i] = (handle) _beginthreadex (NULL,0, threadfun, NULL,0, NULL); -  - waitformultipleobjects (thread_num, handle, TRUE, INFINITE); -printf"there are%d users logged in after logging the result is%d\n", thread_num, g_nlogincount); -     } -     return 0; in}

The results of the operation are as Follows:

Now the results come to the bottom, obviously there are 50 threads executed g_nlogincount++, operation, But the result output is indeterminate, it may be 50, but it may be less than 50.

To solve this problem, we analyze the g_nlogincount++; In the VC6.0 compiler to g_nlogincount++; this statement breaks a breakpoint, then press F5 to enter the debug state, then press the Disassembly button on the debug toolbar, and the Assembly code window Appears. It can be found that a simple self-increment statement in the C + + language is actually made up of three assembly code, as shown IN.

Explain the following three articles of assembly meaning:

The first assembly reads the value of G_nlogincount from memory into the register eax.

The second assembly adds the value in the register EAX to 1, and the result is still stored in the Register eax.

The third assembly writes the values in the register eax back into Memory.

The cause of The problem should be: a to the second sentence, execute b, assuming that B after execution, continue to execute a, in fact register EAX will revert to the last value of a, so that the result is the execution result of thread B is covered by a, the equivalent of B is not executed.

Note: the registers for each thread are private, and the values in each register are saved when the thread is Switched.

therefore, when reading and writing a variable in a multithreaded environment, we need a way to ensure that an incremental operation on a value is Atomic--that is, non-disruptive, that when a thread performs an atomic operation, the other thread must wait for it to complete before it can begin executing the atomic Operation. This hardware-related operation will be complicated, fortunately, the Windows system provides us with some functions beginning with interlocked to accomplish this task (these functions are called interlocked series functions below).

Some common interlocked series functions are listed Below:

1. Increase or decrease operation

Long__cdecl interlockedincrement (LONG volatile* Addend); Long__cdecl interlockeddecrement (LONG volatile* Addend); Returns the value of the variable after the increment or decrement operation is Performed.
Long__cdec interlockedexchangeadd (long volatile* Addend, long value); Returns the value after the operation, note! Adding a negative number is Minus.

2. Assignment operation

Long__cdecl interlockedexchange (long volatile* Target, Long Value); Value is the new value, and the function returns the original Value.

In this case, you can just use the InterlockedIncrement () Function. Change the thread function code to:

1Unsignedint__stdcall Threadfun (void*PPM)2 {3Sleep ( -);//some work should4     //g_nlogincount++;5InterlockedIncrement (lplong) &g_nlogincount);6Sleep ( -);7     return 0;8}

Run again, and you can see that the results will be Unique.

therefore, in the multi-threaded environment, we have to think carefully about these simple statements of variable self-increment, to prevent the data access error caused by multiple threads. For more information, please visit the synchronization functions section on Msdn.

[OS] multithreading-atomic operation Interlocked series functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.