c++多线程例(互斥体,共同访问)

  1. <pre name="code" class="cpp">//这是2个线程模拟卖火车票的小程序  
  2. #include <windows.h>  
  3. #include <iostream.h>  
  4.   
  5. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data  
  6. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data  
  7.   
  8. int index=0;  
  9. int tickets=10;  
  10. HANDLE hMutex;  
  11. void main()  
  12. {  
  13.     HANDLE hThread1;  
  14.     HANDLE hThread2;  
  15.     //创建线程  
  16.   
  17.     hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);  
  18.     hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);  
  19.     CloseHandle(hThread1);  
  20.     CloseHandle(hThread2);  
  21.   
  22.     //创建互斥对象  
  23.     hMutex=CreateMutex(NULL,TRUE,"tickets");  
  24.     if (hMutex)  
  25.     {  
  26.         if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在  
  27.         {  
  28.         // 如果已有互斥量存在则释放句柄并复位互斥量  
  29.         CloseHandle(m_hMutex);  
  30.         m_hMutex = NULL;  
  31.             cout<<"only one instance can run!"<<endl;  
  32.             return;  
  33.         }  
  34.     }  
  35.     WaitForSingleObject(hMutex,INFINITE);  
  36.     ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)  
  37.     ReleaseMutex(hMutex);//谁申请谁施放  
  38.       
  39.     Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?  
  40. }  
  41. //线程1的入口函数  
  42. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data  
  43. {  
  44.     while (true)//无限循环线程  
  45.     {  
  46.         WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行  
  47.         if (tickets>0)  
  48.         {  
  49.             Sleep(1);  
  50.             cout<<"thread1 sell ticket :"<<tickets--<<endl;  
  51.         }  
  52.         else  
  53.             break;  
  54.         ReleaseMutex(hMutex);//施放互斥体  
  55.     }  
  56.   
  57.     return 0;  
  58. }  
  59. //线程2的入口函数  
  60. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data  
  61. {  
  62.     while (true)  
  63.     {  
  64.         WaitForSingleObject(hMutex,INFINITE);  
  65.         if (tickets>0)  
  66.         {  
  67.             Sleep(1);  
  68.             cout<<"thread2 sell ticket :"<<tickets--<<endl;  
  69.         }  
  70.         else  
  71.             break;  
  72.         ReleaseMutex(hMutex);  
  73.     }  
  74.       
  75.     return 0;  
  76. }  
  77. //详解  
  78. HANDLE CreateMutex(  
  79.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针  
  80.  BOOL bInitialOwner, // 初始化互斥对象的所有者  
  81.  LPCTSTR lpName // 指向互斥对象名的指针  
  82. );  
  83. 参数   
  84. lpMutexAttributes   
  85. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。       
  86. bInitialOwner   
  87. 布尔类型,决定互斥体的创建者是否为拥有者   
  88. lpName   
  89. 指向互斥体名字字符串的指针。互斥体可以有名字。   
  90. 互斥体的好处是可以在进程间共享</pre><br>  
  91. <br>  
  92. <pre></pre>  
  93. <pre name="code" class="cpp"></pre><pre name="code" class="cpp"></pre>  
  94. <pre></pre>  
  95. <pre></pre>  
  96. <pre></pre>  
  97.      
  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;  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.   
  5. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data  
  6. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data  
  7.   
  8. int index=0;  
  9. int tickets=10;  
  10. HANDLE hMutex;  
  11. void main()  
  12. {  
  13.     HANDLE hThread1;  
  14.     HANDLE hThread2;  
  15.     //创建线程  
  16.   
  17.     hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);  
  18.     hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);  
  19.     CloseHandle(hThread1);  
  20.     CloseHandle(hThread2);  
  21.   
  22.     //创建互斥对象  
  23.     hMutex=CreateMutex(NULL,TRUE,"tickets");  
  24.     if (hMutex)  
  25.     {  
  26.         if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在  
  27.         {  
  28.         // 如果已有互斥量存在则释放句柄并复位互斥量  
  29.         CloseHandle(m_hMutex);  
  30.         m_hMutex = NULL;  
  31.             cout<<"only one instance can run!"<<endl;  
  32.             return;  
  33.         }  
  34.     }  
  35.     WaitForSingleObject(hMutex,INFINITE);  
  36.     ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)  
  37.     ReleaseMutex(hMutex);//谁申请谁施放  
  38.       
  39.     Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?  
  40. }  
  41. //线程1的入口函数  
  42. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data  
  43. {  
  44.     while (true)//无限循环线程  
  45.     {  
  46.         WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行  
  47.         if (tickets>0)  
  48.         {  
  49.             Sleep(1);  
  50.             cout<<"thread1 sell ticket :"<<tickets--<<endl;  
  51.         }  
  52.         else  
  53.             break;  
  54.         ReleaseMutex(hMutex);//施放互斥体  
  55.     }  
  56.   
  57.     return 0;  
  58. }  
  59. //线程2的入口函数  
  60. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data  
  61. {  
  62.     while (true)  
  63.     {  
  64.         WaitForSingleObject(hMutex,INFINITE);  
  65.         if (tickets>0)  
  66.         {  
  67.             Sleep(1);  
  68.             cout<<"thread2 sell ticket :"<<tickets--<<endl;  
  69.         }  
  70.         else  
  71.             break;  
  72.         ReleaseMutex(hMutex);  
  73.     }  
  74.       
  75.     return 0;  
  76. }  
  77. //详解  
  78. HANDLE CreateMutex(  
  79.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针  
  80.  BOOL bInitialOwner, // 初始化互斥对象的所有者  
  81.  LPCTSTR lpName // 指向互斥对象名的指针  
  82. );  
  83. 参数   
  84. lpMutexAttributes   
  85. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。       
  86. bInitialOwner   
  87. 布尔类型,决定互斥体的创建者是否为拥有者   
  88. lpName   
  89. 指向互斥体名字字符串的指针。互斥体可以有名字。   
  90. 互斥体的好处是可以在进程间共享</pre><br>  
  91. <br>  
  92. <pre></pre>  
  93. <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;  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;  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>  
  94. <pre></pre>  
  95. <pre></pre>  
  96. <pre></pre>  
  97.      
  1. //这是2个线程模拟卖火车票的小程序  
  2. #include <windows.h>  
  3. #include <iostream.h>  
  4.   
  5. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data  
  6. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data  
  7.   
  8. int index=0;  
  9. int tickets=10;  
  10. HANDLE hMutex;  
  11. void main()  
  12. {  
  13.     HANDLE hThread1;  
  14.     HANDLE hThread2;  
  15.     //创建线程  
  16.   
  17.     hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);  
  18.     hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);  
  19.     CloseHandle(hThread1);  
  20.     CloseHandle(hThread2);  
  21.   
  22.     //创建互斥对象  
  23.     hMutex=CreateMutex(NULL,TRUE,"tickets");  
  24.     if (hMutex)  
  25.     {  
  26.         if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在  
  27.         {  
  28.         // 如果已有互斥量存在则释放句柄并复位互斥量  
  29.         CloseHandle(m_hMutex);  
  30.         m_hMutex = NULL;  
  31.             cout<<"only one instance can run!"<<endl;  
  32.             return;  
  33.         }  
  34.     }  
  35.     WaitForSingleObject(hMutex,INFINITE);  
  36.     ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)  
  37.     ReleaseMutex(hMutex);//谁申请谁施放  
  38.       
  39.     Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?  
  40. }  
  41. //线程1的入口函数  
  42. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data  
  43. {  
  44.     while (true)//无限循环线程  
  45.     {  
  46.         WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行  
  47.         if (tickets>0)  
  48.         {  
  49.             Sleep(1);  
  50.             cout<<"thread1 sell ticket :"<<tickets--<<endl;  
  51.         }  
  52.         else  
  53.             break;  
  54.         ReleaseMutex(hMutex);//施放互斥体  
  55.     }  
  56.   
  57.     return 0;  
  58. }  
  59. //线程2的入口函数  
  60. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data  
  61. {  
  62.     while (true)  
  63.     {  
  64.         WaitForSingleObject(hMutex,INFINITE);  
  65.         if (tickets>0)  
  66.         {  
  67.             Sleep(1);  
  68.             cout<<"thread2 sell ticket :"<<tickets--<<endl;  
  69.         }  
  70.         else  
  71.             break;  
  72.         ReleaseMutex(hMutex);  
  73.     }  
  74.       
  75.     return 0;  
  76. }  
  77. //详解  
  78. HANDLE CreateMutex(  
  79.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针  
  80.  BOOL bInitialOwner, // 初始化互斥对象的所有者  
  81.  LPCTSTR lpName // 指向互斥对象名的指针  
  82. );  
  83. 参数   
  84. lpMutexAttributes   
  85. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。       
  86. bInitialOwner   
  87. 布尔类型,决定互斥体的创建者是否为拥有者   
  88. lpName   
  89. 指向互斥体名字字符串的指针。互斥体可以有名字。   
  90. 互斥体的好处是可以在进程间共享  
  1. //这是2个线程模拟卖火车票的小程序  
  2. #include <windows.h>  
  3. #include <iostream.h>  
  4.   
  5. DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data  
  6. DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data  
  7.   
  8. int index=0;  
  9. int tickets=10;  
  10. HANDLE hMutex;  
  11. void main()  
  12. {  
  13.     HANDLE hThread1;  
  14.     HANDLE hThread2;  
  15.     //创建线程  
  16.   
  17.     hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);  
  18.     hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);  
  19.     CloseHandle(hThread1);  
  20.     CloseHandle(hThread2);  
  21.   
  22.     //创建互斥对象  
  23.     hMutex=CreateMutex(NULL,TRUE,"tickets");  
  24.     if (hMutex)  
  25.     {  
  26.         if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在  
  27.         {  
  28.         // 如果已有互斥量存在则释放句柄并复位互斥量  
  29.         CloseHandle(m_hMutex);  
  30.         m_hMutex = NULL;  
  31.             cout<<"only one instance can run!"<<endl;  
  32.             return;  
  33.         }  
  34.     }  
  35.     WaitForSingleObject(hMutex,INFINITE);  
  36.     ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)  
  37.     ReleaseMutex(hMutex);//谁申请谁施放  
  38.       
  39.     Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?  
  40. }  
  41. //线程1的入口函数  
  42. DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data  
  43. {  
  44.     while (true)//无限循环线程  
  45.     {  
  46.         WaitForSingleObject(hMutex,INFINITE);//得到互斥体才能执行  
  47.         if (tickets>0)  
  48.         {  
  49.             Sleep(1);  
  50.             cout<<"thread1 sell ticket :"<<tickets--<<endl;  
  51.         }  
  52.         else  
  53.             break;  
  54.         ReleaseMutex(hMutex);//施放互斥体  
  55.     }  
  56.   
  57.     return 0;  
  58. }  
  59. //线程2的入口函数  
  60. DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data  
  61. {  
  62.     while (true)  
  63.     {  
  64.         WaitForSingleObject(hMutex,INFINITE);  
  65.         if (tickets>0)  
  66.         {  
  67.             Sleep(1);  
  68.             cout<<"thread2 sell ticket :"<<tickets--<<endl;  
  69.         }  
  70.         else  
  71.             break;  
  72.         ReleaseMutex(hMutex);  
  73.     }  
  74.       
  75.     return 0;  
  76. }  
  77. //详解  
  78. HANDLE CreateMutex(  
  79.  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针  
  80.  BOOL bInitialOwner, // 初始化互斥对象的所有者  
  81.  LPCTSTR lpName // 指向互斥对象名的指针  
  82. );  
  83. 参数   
  84. lpMutexAttributes   
  85. 指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。       
  86. bInitialOwner   
  87. 布尔类型,决定互斥体的创建者是否为拥有者   
  88. lpName   
  89. 指向互斥体名字字符串的指针。互斥体可以有名字。   
  90. 互斥体的好处是可以在进程间共享  
//这是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 
指向互斥体名字字符串的指针。互斥体可以有名字。 
互斥体的好处是可以在进程间共享


  1.   
  1.   

  1.   
  1.   
jpg 改 rar 

原文地址:https://www.cnblogs.com/kuangke/p/7272563.html