1. <pre name="code" class="cpp">//这是2个线程模拟卖火车票的小程序
  2. #include <windows.h>
  3. #include <iostream.h>
  4. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
  5. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
  6. int index=0;
  7. int tickets=10;
  8. HANDLE hMutex;
  9. void main()
  10. {
  11. HANDLE hThread1;
  12. HANDLE hThread2;
  13. //创建线程
  14. hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  15. hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  16. CloseHandle(hThread1);
  17. CloseHandle(hThread2);
  18. //创建互斥对象
  19. hMutex=CreateMutex(NULL,TRUE,"tickets");
  20. if (hMutex)
  21. {
  22. if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
  23. {
  24. // 如果已有互斥量存在则释放句柄并复位互斥量
  25.         CloseHandle(m_hMutex);
  26.         m_hMutex = NULL;
  27. cout<<"only one instance can run!"<<endl;
  28. return;
  29. }
  30. }
  31. WaitForSingleObject(hMutex,INFINITE);
  32. ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
  33. ReleaseMutex(hMutex);//谁申请谁施放
  34. Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
  35. }
  36. //线程1的入口函数
  37. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
  38. {
  39. while (true)//无限循环线程
  40. {
  41. WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行
  42. if (tickets>0)
  43. {
  44. Sleep(1);
  45. cout<<"thread1 sell ticket :"<<tickets--<<endl;
  46. }
  47. else
  48. break;
  49. ReleaseMutex(hMutex);//施放互斥体
  50. }
  51. return 0;
  52. }
  53. //线程2的入口函数
  54. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
  55. {
  56. while (true)
  57. {
  58. WaitForSingleObject(hMutex,INFINITE);
  59. if (tickets>0)
  60. {
  61. Sleep(1);
  62. cout<<"thread2 sell ticket :"<<tickets--<<endl;
  63. }
  64. else
  65. break;
  66. ReleaseMutex(hMutex);
  67. }
  68. return 0;
  69. }
  70. //详解
  71. HANDLE CreateMutex(
  72.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  73.  BOOL bInitialOwner, // 初始化互斥对象的所有者
  74.  LPCTSTR lpName // 指向互斥对象名的指针
  75. );
  76. 参数
  77. lpMutexAttributes
  78. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。
  79. bInitialOwner
  80. 布尔类型,决定互斥体的创建者是否为拥有者
  81. lpName
  82. 指向互斥体名字字符串的指针。互斥体可以有名字。
  83. 互斥体的好处是可以在进程间共享</pre><br>
  84. <br>
  85. <pre></pre>
  86. <pre name="code" class="cpp"></pre><pre name="code" class="cpp"></pre>
  87. <pre></pre>
  88. <pre></pre>
  89. <pre></pre>
  1. <div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" target="_blank">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" target="_blank">copy</a><div style="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="0" height="0" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=0&height=0" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" target="_blank">print</a></span><a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;" target="_blank">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="comment">//这是2个线程模拟卖火车票的小程序</span><span>  </span></span></li><li class=""><span><span class="preprocessor">#include <windows.h></span><span>  </span></span></li><li class="alt"><span><span class="preprocessor">#include <iostream.h></span><span>  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="datatypes">DWORD</span><span> WINAPI Fun1Proc(</span><span class="datatypes">LPVOID</span><span> lpParameter);</span><span class="comment">//thread data</span><span>  </span></span></li><li class=""><span><span class="datatypes">DWORD</span><span> WINAPI Fun2Proc(</span><span class="datatypes">LPVOID</span><span> lpParameter);</span><span class="comment">//thread data</span><span>  </span></span></li><li class="alt"><span>  </span></li><li class=""><span><span class="datatypes">int</span><span> index=0;  </span></span></li><li class="alt"><span><span class="datatypes">int</span><span> tickets=10;  </span></span></li><li class=""><span><span class="datatypes">HANDLE</span><span> hMutex;  </span></span></li><li class="alt"><span><span class="keyword">void</span><span> main()  </span></span></li><li class=""><span>{  </span></li><li class="alt"><span>    <span class="datatypes">HANDLE</span><span> hThread1;  </span></span></li><li class=""><span>    <span class="datatypes">HANDLE</span><span> hThread2;  </span></span></li><li class="alt"><span>    <span class="comment">//创建线程</span><span>  </span></span></li><li class=""><span>  </span></li><li class="alt"><span>    hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);  </span></li><li class=""><span>    hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);  </span></li><li class="alt"><span>    CloseHandle(hThread1);  </span></li><li class=""><span>    CloseHandle(hThread2);  </span></li><li class="alt"><span>  </span></li><li class=""><span>    <span class="comment">//创建互斥对象</span><span>  </span></span></li><li class="alt"><span>    hMutex=CreateMutex(NULL,TRUE,<span class="string">"tickets"</span><span>);  </span></span></li><li class=""><span>    <span class="keyword">if</span><span> (hMutex)  </span></span></li><li class="alt"><span>    {  </span></li><li class=""><span>        <span class="keyword">if</span><span> (ERROR_ALREADY_EXISTS==GetLastError())</span><span class="comment">//得到错误:已经存在</span><span>  </span></span></li><li class="alt"><span>        {  </span></li><li class=""><span>        <span class="comment">// 如果已有互斥量存在则释放句柄并复位互斥量</span><span>  </span></span></li><li class="alt"><span>        CloseHandle(m_hMutex);  </span></li><li class=""><span>        m_hMutex = NULL;  </span></li><li class="alt"><span>            cout<<<span class="string">"only one instance can run!"</span><span><<endl;  </span></span></li><li class=""><span>            <span class="keyword">return</span><span>;  </span></span></li><li class="alt"><span>        }  </span></li><li class=""><span>    }  </span></li><li class="alt"><span>    WaitForSingleObject(hMutex,INFINITE);  </span></li><li class=""><span>    ReleaseMutex(hMutex);<span class="comment">//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)</span><span>  </span></span></li><li class="alt"><span>    ReleaseMutex(hMutex);<span class="comment">//谁申请谁施放</span><span>  </span></span></li><li class=""><span>      </span></li><li class="alt"><span>    Sleep(4000);<span class="comment">//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?</span><span>  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span><span class="comment">//线程1的入口函数</span><span>  </span></span></li><li class=""><span><span class="datatypes">DWORD</span><span> WINAPI Fun1Proc(</span><span class="datatypes">LPVOID</span><span> lpParameter)</span><span class="comment">//thread data</span><span>  </span></span></li><li class="alt"><span>{  </span></li><li class=""><span>    <span class="keyword">while</span><span> (</span><span class="keyword">true</span><span>)</span><span class="comment">//无限循环线程</span><span>  </span></span></li><li class="alt"><span>    {  </span></li><li class=""><span>        WaitForSingleObject(hMutex,INFINITE);<span class="comment">//得到互斥体才能执行</span><span>  </span></span></li><li class="alt"><span>        <span class="keyword">if</span><span> (tickets>0)  </span></span></li><li class=""><span>        {  </span></li><li class="alt"><span>            Sleep(1);  </span></li><li class=""><span>            cout<<<span class="string">"thread1 sell ticket :"</span><span><<tickets--<<endl;  </span></span></li><li class="alt"><span>        }  </span></li><li class=""><span>        <span class="keyword">else</span><span>  </span></span></li><li class="alt"><span>            <span class="keyword">break</span><span>;  </span></span></li><li class=""><span>        ReleaseMutex(hMutex);<span class="comment">//施放互斥体</span><span>  </span></span></li><li class="alt"><span>    }  </span></li><li class=""><span>  </span></li><li class="alt"><span>    <span class="keyword">return</span><span> 0;  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span><span class="comment">//线程2的入口函数</span><span>  </span></span></li><li class=""><span><span class="datatypes">DWORD</span><span> WINAPI Fun2Proc(</span><span class="datatypes">LPVOID</span><span> lpParameter)</span><span class="comment">//thread data</span><span>  </span></span></li><li class="alt"><span>{  </span></li><li class=""><span>    <span class="keyword">while</span><span> (</span><span class="keyword">true</span><span>)  </span></span></li><li class="alt"><span>    {  </span></li><li class=""><span>        WaitForSingleObject(hMutex,INFINITE);  </span></li><li class="alt"><span>        <span class="keyword">if</span><span> (tickets>0)  </span></span></li><li class=""><span>        {  </span></li><li class="alt"><span>            Sleep(1);  </span></li><li class=""><span>            cout<<<span class="string">"thread2 sell ticket :"</span><span><<tickets--<<endl;  </span></span></li><li class="alt"><span>        }  </span></li><li class=""><span>        <span class="keyword">else</span><span>  </span></span></li><li class="alt"><span>            <span class="keyword">break</span><span>;  </span></span></li><li class=""><span>        ReleaseMutex(hMutex);  </span></li><li class="alt"><span>    }  </span></li><li class=""><span>      </span></li><li class="alt"><span>    <span class="keyword">return</span><span> 0;  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span><span class="comment">//详解</span><span>  </span></span></li><li class=""><span><span class="datatypes">HANDLE</span><span> CreateMutex(  </span></span></li><li class="alt"><span> LPSECURITY_ATTRIBUTES lpMutexAttributes, <span class="comment">// 指向安全属性的指针</span><span>  </span></span></li><li class=""><span> <span class="datatypes">BOOL</span><span> bInitialOwner, </span><span class="comment">// 初始化互斥对象的所有者</span><span>  </span></span></li><li class="alt"><span> <span class="datatypes">LPCTSTR</span><span> lpName </span><span class="comment">// 指向互斥对象名的指针</span><span>  </span></span></li><li class=""><span>);  </span></li><li class="alt"><span>参数   </span></li><li class=""><span>lpMutexAttributes   </span></li><li class="alt"><span>指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。       </span></li><li class=""><span>bInitialOwner   </span></li><li class="alt"><span>布尔类型,决定互斥体的创建者是否为拥有者   </span></li><li class=""><span>lpName   </span></li><li class="alt"><span>指向互斥体名字字符串的指针。互斥体可以有名字。   </span></li><li class=""><span>互斥体的好处是可以在进程间共享  </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">//这是2个线程模拟卖火车票的小程序
  2. #include <windows.h>
  3. #include <iostream.h>
  4. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
  5. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
  6. int index=0;
  7. int tickets=10;
  8. HANDLE hMutex;
  9. void main()
  10. {
  11. HANDLE hThread1;
  12. HANDLE hThread2;
  13. //创建线程
  14. hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  15. hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  16. CloseHandle(hThread1);
  17. CloseHandle(hThread2);
  18. //创建互斥对象
  19. hMutex=CreateMutex(NULL,TRUE,"tickets");
  20. if (hMutex)
  21. {
  22. if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
  23. {
  24. // 如果已有互斥量存在则释放句柄并复位互斥量
  25.         CloseHandle(m_hMutex);
  26.         m_hMutex = NULL;
  27. cout<<"only one instance can run!"<<endl;
  28. return;
  29. }
  30. }
  31. WaitForSingleObject(hMutex,INFINITE);
  32. ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
  33. ReleaseMutex(hMutex);//谁申请谁施放
  34. Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
  35. }
  36. //线程1的入口函数
  37. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
  38. {
  39. while (true)//无限循环线程
  40. {
  41. WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行
  42. if (tickets>0)
  43. {
  44. Sleep(1);
  45. cout<<"thread1 sell ticket :"<<tickets--<<endl;
  46. }
  47. else
  48. break;
  49. ReleaseMutex(hMutex);//施放互斥体
  50. }
  51. return 0;
  52. }
  53. //线程2的入口函数
  54. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
  55. {
  56. while (true)
  57. {
  58. WaitForSingleObject(hMutex,INFINITE);
  59. if (tickets>0)
  60. {
  61. Sleep(1);
  62. cout<<"thread2 sell ticket :"<<tickets--<<endl;
  63. }
  64. else
  65. break;
  66. ReleaseMutex(hMutex);
  67. }
  68. return 0;
  69. }
  70. //详解
  71. HANDLE CreateMutex(
  72.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  73.  BOOL bInitialOwner, // 初始化互斥对象的所有者
  74.  LPCTSTR lpName // 指向互斥对象名的指针
  75. );
  76. 参数
  77. lpMutexAttributes
  78. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。
  79. bInitialOwner
  80. 布尔类型,决定互斥体的创建者是否为拥有者
  81. lpName
  82. 指向互斥体名字字符串的指针。互斥体可以有名字。
  83. 互斥体的好处是可以在进程间共享</pre><br>
  84. <br>
  85. <pre></pre>
  86. <div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" target="_blank">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" target="_blank">copy</a><div style="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="0" height="0" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=0&height=0" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" target="_blank">print</a></span><a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;" target="_blank">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>  </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;"></pre><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" target="_blank">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" target="_blank">copy</a><div style="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="0" height="0" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=0&height=0" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" target="_blank">print</a></span><a href="http://blog.csdn.net/goodai007/article/details/6976081#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;" target="_blank">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>  </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;"></pre>
  87. <pre></pre>
  88. <pre></pre>
  89. <pre></pre>
  1. //这是2个线程模拟卖火车票的小程序
  2. #include <windows.h>
  3. #include <iostream.h>
  4. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
  5. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
  6. int index=0;
  7. int tickets=10;
  8. HANDLE hMutex;
  9. void main()
  10. {
  11. HANDLE hThread1;
  12. HANDLE hThread2;
  13. //创建线程
  14. hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  15. hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  16. CloseHandle(hThread1);
  17. CloseHandle(hThread2);
  18. //创建互斥对象
  19. hMutex=CreateMutex(NULL,TRUE,"tickets");
  20. if (hMutex)
  21. {
  22. if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
  23. {
  24. // 如果已有互斥量存在则释放句柄并复位互斥量
  25.         CloseHandle(m_hMutex);
  26.         m_hMutex = NULL;
  27. cout<<"only one instance can run!"<<endl;
  28. return;
  29. }
  30. }
  31. WaitForSingleObject(hMutex,INFINITE);
  32. ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
  33. ReleaseMutex(hMutex);//谁申请谁施放
  34. Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
  35. }
  36. //线程1的入口函数
  37. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
  38. {
  39. while (true)//无限循环线程
  40. {
  41. WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行
  42. if (tickets>0)
  43. {
  44. Sleep(1);
  45. cout<<"thread1 sell ticket :"<<tickets--<<endl;
  46. }
  47. else
  48. break;
  49. ReleaseMutex(hMutex);//施放互斥体
  50. }
  51. return 0;
  52. }
  53. //线程2的入口函数
  54. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
  55. {
  56. while (true)
  57. {
  58. WaitForSingleObject(hMutex,INFINITE);
  59. if (tickets>0)
  60. {
  61. Sleep(1);
  62. cout<<"thread2 sell ticket :"<<tickets--<<endl;
  63. }
  64. else
  65. break;
  66. ReleaseMutex(hMutex);
  67. }
  68. return 0;
  69. }
  70. //详解
  71. HANDLE CreateMutex(
  72.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  73.  BOOL bInitialOwner, // 初始化互斥对象的所有者
  74.  LPCTSTR lpName // 指向互斥对象名的指针
  75. );
  76. 参数
  77. lpMutexAttributes
  78. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。
  79. bInitialOwner
  80. 布尔类型,决定互斥体的创建者是否为拥有者
  81. lpName
  82. 指向互斥体名字字符串的指针。互斥体可以有名字。
  83. 互斥体的好处是可以在进程间共享
  1. //这是2个线程模拟卖火车票的小程序
  2. #include <windows.h>
  3. #include <iostream.h>
  4. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
  5. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
  6. int index=0;
  7. int tickets=10;
  8. HANDLE hMutex;
  9. void main()
  10. {
  11. HANDLE hThread1;
  12. HANDLE hThread2;
  13. //创建线程
  14. hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  15. hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  16. CloseHandle(hThread1);
  17. CloseHandle(hThread2);
  18. //创建互斥对象
  19. hMutex=CreateMutex(NULL,TRUE,"tickets");
  20. if (hMutex)
  21. {
  22. if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
  23. {
  24. // 如果已有互斥量存在则释放句柄并复位互斥量
  25.         CloseHandle(m_hMutex);
  26.         m_hMutex = NULL;
  27. cout<<"only one instance can run!"<<endl;
  28. return;
  29. }
  30. }
  31. WaitForSingleObject(hMutex,INFINITE);
  32. ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
  33. ReleaseMutex(hMutex);//谁申请谁施放
  34. Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
  35. }
  36. //线程1的入口函数
  37. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
  38. {
  39. while (true)//无限循环线程
  40. {
  41. WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行
  42. if (tickets>0)
  43. {
  44. Sleep(1);
  45. cout<<"thread1 sell ticket :"<<tickets--<<endl;
  46. }
  47. else
  48. break;
  49. ReleaseMutex(hMutex);//施放互斥体
  50. }
  51. return 0;
  52. }
  53. //线程2的入口函数
  54. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
  55. {
  56. while (true)
  57. {
  58. WaitForSingleObject(hMutex,INFINITE);
  59. if (tickets>0)
  60. {
  61. Sleep(1);
  62. cout<<"thread2 sell ticket :"<<tickets--<<endl;
  63. }
  64. else
  65. break;
  66. ReleaseMutex(hMutex);
  67. }
  68. return 0;
  69. }
  70. //详解
  71. HANDLE CreateMutex(
  72.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  73.  BOOL bInitialOwner, // 初始化互斥对象的所有者
  74.  LPCTSTR lpName // 指向互斥对象名的指针
  75. );
  76. 参数
  77. lpMutexAttributes
  78. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。
  79. bInitialOwner
  80. 布尔类型,决定互斥体的创建者是否为拥有者
  81. lpName
  82. 指向互斥体名字字符串的指针。互斥体可以有名字。
  83. 互斥体的好处是可以在进程间共享
//这是2个线程模拟卖火车票的小程序
#include <windows.h>
#include <iostream.h> DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data int index=0;
int tickets=10;
HANDLE hMutex;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
//创建线程 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2); //创建互斥对象
hMutex=CreateMutex(NULL,TRUE,"tickets");
if (hMutex)
{
if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
{
// 如果已有互斥量存在则释放句柄并复位互斥量
  CloseHandle(m_hMutex);
  m_hMutex = NULL;
cout<<"only one instance can run!"<<endl;
return;
}
}
WaitForSingleObject(hMutex,INFINITE);
ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
ReleaseMutex(hMutex);//谁申请谁施放 Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
while (true)//无限循环线程
{
WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行
if (tickets>0)
{
Sleep(1);
cout<<"thread1 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);//施放互斥体
} return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
{
while (true)
{
WaitForSingleObject(hMutex,INFINITE);
if (tickets>0)
{
Sleep(1);
cout<<"thread2 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
} return 0;
}
//详解
HANDLE CreateMutex(
 LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
 BOOL bInitialOwner, // 初始化互斥对象的所有者
 LPCTSTR lpName // 指向互斥对象名的指针
);
参数
lpMutexAttributes
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。
bInitialOwner
布尔类型,决定互斥体的创建者是否为拥有者
lpName
指向互斥体名字字符串的指针。互斥体可以有名字。
互斥体的好处是可以在进程间共享



jpg 改 rar 


c++多线程例(互斥体,共同访问)的更多相关文章

  1. C++多线程同步技巧(三)--- 互斥体

    简介 Windows互斥对象机制. 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问,在线程同步与保证程序单体运行上都有相当大的用处. 代码 ...

  2. 多线程(三)多线程同步_基本介绍及mutex互斥体

    同步进制的引入为了解决以下三个主要问题:1.控制多个线程之间对共享资源访问,保证共享资源的完整性例如:线程A对共享资源进行写入,线程B读取共享资源2.确保多个线程之间的动作以指定的次序发生例如:线程B ...

  3. 【uTenux实验】互斥体

    互斥体,维基百科中交互斥锁.其定义是这样的:互斥锁(英语:英语:Mutual exclusion,缩写 Mutex)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制 ...

  4. linux 内核的rt_mutex (realtime互斥体)

    linux 内核有实时互斥体(锁),名为rt_mutex即realtime mutex.说到realtime一定离不开priority(优先级).所谓实时,就是根据优先级的不同对任务作出不同速度的响应 ...

  5. 互斥体与互锁 <第五篇>

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码“临界区”.因此,在任意时刻,只有一个线程被允许进入这 ...

  6. 总结windows多线程同步互斥

    windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...

  7. Windbg调试互斥体(Mutex)死锁

    一. 测试代码 #include <windows.h> #include <tchar.h> #include <process.h> HANDLE hMutex ...

  8. 转载 互斥体与互锁 <第五篇>

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码“临界区”.因此,在任意时刻,只有一个线程被允许进入这 ...

  9. windows多线程同步互斥--总结

    我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...

随机推荐

  1. IIS6 伪静态 IIS文件类型映射配置方法 【图解】

    1.右键点击 要设置网站的网站 2.属性 -->主目录 -->配置--> 3.如右侧窗口,找到 .aspx 扩展名-->编辑-->复制 可执行文件的路径-->关闭 ...

  2. DDMS android 开发工具-----dump View Hierarchy for UI automator

    今天又发现一个好工具  dump View Hierarchy 对学习UI布局非常有优点,操作也非常easy的.直接上图说话了 watermark/2/text/aHR0cDovL2Jsb2cuY3N ...

  3. wpa_cli 连接 wifi(转)

    wpa_cli 连接 wifi 转自:http://hi.baidu.com/yyangjjun/item/9dfe8e175439fc7a1009b5ba   1: run wpa_supplica ...

  4. TIME_WAIT详解

    1.TCP四次挥手关闭链接过程 2.TIME_WAIT的产生条件主动关闭方在发送四次挥手的最后一个ACK会变为TIME_WAIT状态,保留此状态的时间为两个MSL 3.TIME_WAIT两个MSL的作 ...

  5. HTTP 403详解

    1.什么是Http 403错误Http协议中对403错误定义如下The server understood the request, but is refusing to fulfill it. Au ...

  6. Java Mail(三):Session、Message详解

    http://blog.csdn.net/ghsau/article/details/17909093 ************************************* 本文来自:高爽|Co ...

  7. jquer WdatePicker 使用 手册

    1. 跨无限级框架显示 无论你把日期控件放在哪里,你都不需要担心会被外层的iframe所遮挡进而影响客户体验,因为My97日期控件是可以跨无限级框架显示的 示例2-7 跨无限级框架演示 可无限跨越框架 ...

  8. love2d 0.9发布

    2013年12月13(有点遗憾,一个星期后才知道),love2d终于发布新版本了, 可以直接从我的百度网盘下载. 主要的更新有:(简单翻译自官方论坛说明) LuaJIT: 默认使用LuaJIT,性能大 ...

  9. 缓存技术PK:选择Memcached还是Redis(转)

    [IT168 技术]要Memcached还是要Redis?在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应 ...

  10. gitolite

    gitolite: https://github.com/sitaramc/gitolite https://github.com/sitaramc/gitolite/tags