Windows condition variables

Source: Internet
Author: User

See Msdn:http://msdn.microsoft.com/en-us/library/windows/desktop/ms686903%28v=vs.85%29.aspx for details

As we have seen, you can use Srwlock when you want the writer thread and the reader thread to access a resource in exclusive or shared ways. In these cases, if the reader thread has no data to read, it should release the lock and wait until the writer thread has produced new data. If the data structure that is used to receive the writer thread is full, the writer should also release Srwlock and go to sleep until the thread is read to clear the structure.

We want the thread to release the lock in an atomic manner and block itself until a certain condition is established. It is more complicated to implement such a thread synchronization. Windows provides a condition variable to help us do this by Sleepconditionvariablecs (critical section) or the SLEEPCONDITIONVARIABLESRW function.

When the thread detects that the appropriate condition is satisfied (for example, there is data for the reader to use), it calls Wakeconditionvariable or wakeallconditionvariable, so that the thread that blocks in the sleep* function is awakened.

Take a look at the code first:

[CPP]View Plaincopy
  1. //Condition variable. CPP: The entry point that defines the console application.   
  2. //   
  3. #include "stdafx.h"   
  4. #include <windows.h>   
  5. #include <iostream>   
  6. #include <vector>   
  7. #include <process.h>   
  8. using   namespace std;
  9. DWORD  WINAPI threadproduce (PVOID pvparam);
  10. DWORD  WINAPI ThreadUser1 (PVOID pvparam);
  11. DWORD  WINAPI ThreadUser2 (PVOID pvparam);
  12. vector<int> Ivec;
  13. SRWLOCK G_lock;
  14. SRWLOCK G_lock2;
  15. Condition_variable G_conditionvar;
  16. int _tmain (int argc, _tchar* argv[])
  17. {
  18. Initializesrwlock (&g_lock); //Initialize lock   
  19. //Create producer   
  20. HANDLE hThread1 = (HANDLE) _beginthreadex (null,0, ( unsigned int(_stdcall *) ( void *))  threadproduce,null,0,0);
  21. //Create reader thread   
  22. HANDLE hThread2 = (HANDLE) _beginthreadex (null,0, (unsigned int(_stdcall *  ) (void*)) threaduser1,null,0,0);
  23. HANDLE hThread3 = (HANDLE) _beginthreadex (null,0, ( unsigned int(_stdcall *) ( void *))  threaduser2,null,0,0);
  24. CloseHandle (HTHREAD1);
  25. CloseHandle (HTHREAD2);
  26. CloseHandle (HTHREAD3);
  27. System ("pause");
  28. return  0;
  29. }
  30. DWORD WINAPI threadproduce (PVOID pvparam)
  31. {
  32. for (int i=0; i<10; ++i)
  33. {
  34. Acquiresrwlockexclusive (&g_lock); //Get SRW lock   
  35. Ivec.push_back (i);
  36. Releasesrwlockexclusive (&g_lock); //Release SRW lock   
  37. Wakeconditionvariable (&g_conditionvar); //Because, after each execution of the push_back, there must be at least one element in the container (producer   
  38. //produce something) the thread that is blocking in the sleep* is awakened (the thread that reads the sleep).   
  39. Sleep (1000); //Stop, let the reader read first if not wait, may lead to vector empty before pop error
  40. }
  41. return  0;
  42. }
  43. DWORD WINAPI ThreadUser1 (PVOID pvparam)
  44. {
  45. while (1)
  46. {
  47. Acquiresrwlockexclusive (&g_lock);
  48. while (Ivec.empty ())
  49. {
  50. cout<<"Waiting to be written"<<endl;
  51. //If the container is empty, that is, no content can be read, then let the thread go to sleep until wakeconditionallvariable (&g_conditionvar) is called;   
  52. SLEEPCONDITIONVARIABLESRW (&g_conditionvar,&g_lock,infinite,condition_variable_lockmode_shared);
  53. }
  54. cout<<"Thread 1:"<<ivec.back () <<endl;
  55. Ivec.pop_back ();
  56. Releasesrwlockexclusive (&g_lock);
  57. }
  58. return  0;
  59. }
  60. DWORD WINAPI ThreadUser2 (PVOID pvparam)
  61. {
  62. while (1)
  63. {
  64. Acquiresrwlockexclusive (&g_lock);
  65. while (Ivec.empty ())
  66. {
  67. cout<<"Waiting to be written"<<endl;
  68. SLEEPCONDITIONVARIABLESRW (&g_conditionvar,&g_lock,infinite,condition_variable_lockmode_shared);
  69. }
  70. cout<<"Thread 2:"<<ivec.back () <<endl;
  71. Ivec.pop_back ();
  72. Releasesrwlockexclusive (&g_lock);
  73. }
  74. return  0;
  75. }


Analyzing this code is very simple and can be seen in code annotations. Before, there were a few mistakes in writing this code:

(1) Differences between functions of acquiresrwlockexclusive () releasesrwlockexclusive () and Accquiresrwlockshare () Releasesrwlockshare () two

The former obtains exclusive access to the protected resources while the latter obtains the shared access to protect the resources, because although the read thread in the code, while reading the data, he also pop_back () the contents of the container, that is, can be regarded as "write", because we have to obtain exclusive access.

(2) The difference between Wakeconditionvariabel () and wakeallconditionvariable ():

When the former is called, a thread that waits for the same condition variable to be triggered in the sleepconditionvariable* function is locked and returned. When this thread releases the same lock, it does not wake up other threads that are waiting for the same condition variable

When the latter is called, it causes one or more threads in the sleepconditionvariable* function to wait for the condition variable to trigger access to the resource and return.

(3)

SLEEPCONDITIONVARIABLESRW (  __in_out      conditionvariable,/  /thread sleep-related condition variable  __in_out      SRWLock,                       // Point to a srwlock pointer  __in          dwmilliseconds,//desired time to wait, can be infinite  __in          Flags);
The function performs two operations in the same way as an atomic operation:
1. Release the lock that the srwlock points to;
2. Put the thread to sleep.

If the parameter flags is condition_variable_lockmode_shared, multiple reader threads can be allowed to lock at the same time.

Related Article

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.