Atomic Operation interlocked Series functions (RPM)

Source: Internet
Author: User

On a " multi-threaded first intimate contact CreateThread and _beginthreadex essential Difference " mentioned in 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 long G_nlogincount; //Login times
  5. unsigned int __stdcall fun (void *ppm); //thread function
  6. const int thread_num = 10; //number of startup threads
  7. unsigned int __stdcall threadfun (void *ppm)
  8. {
  9. Sleep (100); //some work should
  10. g_nlogincount++;
  11. Sleep (50);
  12. return 0;
  13. }
  14. int main ()
  15. {
  16. G_nlogincount = 0;
  17. HANDLE Handle[thread_num];
  18. For (int i = 0; i < thread_num; i++)
  19. Handle[i] = (handle) _beginthreadex (null, 0, threadfun, NULL, 0, NULL);
  20. WaitForMultipleObjects (Thread_num, handle, TRUE, INFINITE);
  21. printf ("%d users log results after logging%d\n", Thread_num, G_nlogincount);
  22. return 0;
  23. }

The program simulates the user Login, the program will output the 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 50 user logon process repeated 20 times , the code is as follows:

  1. #include <stdio.h>
  2. #include <windows.h>
  3. Volatile long G_nlogincount; //Login times
  4. unsigned int __stdcall fun (void *ppm); //thread function
  5. Const DWORD thread_num =; Number of startup threads
  6. DWORD WINAPI threadfun (void *ppm)
  7. {
  8. Sleep (100); //some work should
  9. g_nlogincount++;
  10. Sleep (50);
  11. return 0;
  12. }
  13. int main ()
  14. {
  15. printf ("Use of atomic operations interlocked series functions \ n");
  16. printf ("-by Morewindows (http://blog.csdn.net/MoreWindows)--\n\n");
  17. ///Repeat 20 times to observe the conflicts caused by multi-threaded access to the same resource
  18. int num= 20;
  19. While (num--)
  20. {
  21. G_nlogincount = 0;
  22. int i;
  23. HANDLE Handle[thread_num];
  24. For (i = 0; i < thread_num; i++)
  25. Handle[i] = CreateThread (null, 0, threadfun, NULL, 0, NULL);
  26. WaitForMultipleObjects (Thread_num, handle, TRUE, INFINITE);
  27. printf ("%d users log results after logging%d\n", Thread_num, G_nlogincount);
  28. }
  29. return 0;
  30. }

Running results such as:

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

To solve this problem, we will analyzeG_nlogincount++; operation. In the VC6.0 compiler to G_nlogincount+ +; This statement hit a breakpoint, then press F5 to Enter the debug state, and then press the Debug toolbar disassembly button, so that 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.

        So because of the concurrency of thread execution, it is likely that the thread a executes to the second sentence, thread b begins execution, thread b writes the original value to register a the main computed value is thread 50, possibly less than 50.

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, theWindows 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__cdeclinterlockedincrement(long volatile* Addend);

Long__cdeclinterlockeddecrement(long volatile* Addend);

Returns the value of the variable after the increment or decrement operation is performed .

Long__cdec interlockedexchangeadd(long volatile* Addend, longValue) ;

Returns the value after the operation, note! Adding a negative number is minus.

2. Assignment operation

Long__cdeclinterlockedexchange(long volatile* Target, longValue);

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:

    1. DWORD WINAPI threadfun (void *ppm)
    2. {
    3. Sleep (100); //some work should
    4. //g_nlogincount++;
    5. InterlockedIncrement ((lplong) &g_nlogincount);
    6. Sleep (50);
    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 at the address http://msdn.microsoft.com/zh-cn/library/aa909196.aspx

See here, I believe this series first "second multi-threaded the first multi-threaded written test questions summary" in the selection of the first question (Baidu written questions) should be able to kill the second (know it is also know why), the correct answer is D. In addition to an additional question, the program is to use 50 threads to impersonate the user login, interested students can try to use 100 threads to simulate (on the machine to try absolutely will have accidentally found ^_^).

The next "Seconds kill multithreading fourth a classic multi-threaded synchronization problem" will be a little more complicated but very classic multi-threaded synchronization mutex problem, this problem will be used in different ways to answer, so that you fully skilled multi-threaded synchronization mutually exclusive " moves." More exciting, please continue to see.

Reprint please indicate source, original address: http://blog.csdn.net/morewindows/article/details/7429155

If you feel that this article is helpful, please click on the ' top ' support, your support is my greatest motivation to write, thank you.

Atomic Operation interlocked Series functions (RPM)

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.