﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Ah.........FreshMeat.-随笔分类-WIN32编程</title><link>http://www.cppblog.com/sixinquan/category/13106.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 22 Mar 2010 16:38:12 GMT</lastBuildDate><pubDate>Mon, 22 Mar 2010 16:38:12 GMT</pubDate><ttl>60</ttl><item><title>WIN32多线程五 线程同步机制Semaphore</title><link>http://www.cppblog.com/sixinquan/archive/2010/03/15/109713.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Sun, 14 Mar 2010 17:22:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/03/15/109713.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/109713.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/03/15/109713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/109713.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/109713.html</trackback:ping><description><![CDATA[大学操作系统教材里讲的最多的估计就是信号量Semaphore了，具体就不再介绍了，通常用来处理多线程访问多个资源的情况。<br>实际上，如果创建一个信号量，并且它的最大计数是1，那么它就与Mutex等价。<br><br>下面是个生产者-消费者问题的Win32程序，运行时的截图如下:<br><img alt="" src="http://www.cppblog.com/images/cppblog_com/sixinquan/1.jpg" width="453" align="middle" height="215"><br><br>代码如下:<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;生产者-消费者问题是一个经典的进程同步问题，该问题最早由Dijkstra提出；很多计算机问题都可以抽象为生产者-消费者问题。<br>&nbsp;*&nbsp;有1个生产者生产商品放到环形buffer中供5个消费者消费；生产者每次最多生产5个商品，消费者每次消费1个。<br>&nbsp;*&nbsp;要解决这个问题，我们必须确保:(1)并且当缓冲区中没有商品时，消费者不能消费，缓冲区满时，生产者也不能生产商品&nbsp;(2)不同消费者&nbsp;&nbsp;*&nbsp;不能同时消费同一个商品；<br>&nbsp;*<br>&nbsp;*&nbsp;解决(1)我们用一个生产者信号量表示生产者者资源，即空闲buffer数量；用一个消费者信号量表示消费者资源，即非空闲buffer数量。<br>&nbsp;*&nbsp;解决(2)我们用一个互斥量Mutex，得到这个Mutex的消费者才能消费。<br></span><span style="color: #008000;">*/</span><span style="color: #000000;"><br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">time.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;ASSERT(a)&nbsp;if&nbsp;(!(a))&nbsp;\</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE)<br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;MAX_PRODUCE_COUNT&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者每次最多生产数量</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;CONSUMER_COUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">消费者数量</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;BUFFER_SIZE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">缓冲区大小</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;SLEEP_TIME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;WM_FORCE_PAINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(WM_APP+10)</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ProduceAndConsume();<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;EndProduceConsume();<br><br>LRESULT&nbsp;CALLBACK&nbsp;WndProc(HWND,&nbsp;UINT,&nbsp;WPARAM,&nbsp;LPARAM)&nbsp;;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Win32窗口回调函数</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>DWORD&nbsp;&nbsp;&nbsp;&nbsp;WINAPI&nbsp;&nbsp;&nbsp;&nbsp;ProducerThread(LPVOID&nbsp;pVoid);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者线程函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">DWORD&nbsp;&nbsp;&nbsp;&nbsp;WINAPI&nbsp;&nbsp;&nbsp;&nbsp;ConsumerThread(LPVOID&nbsp;pVoid);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者线程函数</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iProducerPointer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">生产者指针，指向可以放商品的的位置</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iConsumerPointer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">消费者指针，指向可以消费商品的位置</span><span style="color: #008000;"><br></span><span style="color: #000000;">HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hProducerSemaphore;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者信号量，初始有20个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hConsumerSemaphore;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者信号量，初始有0个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hConsumerMutex;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">生产者Mutex</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hProducerThread;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">生产者线程，不断生产商品</span><span style="color: #008000;"><br></span><span style="color: #000000;">HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hConsumersThread[CONSUMER_COUNT];&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者线程，不断消费商品</span><span style="color: #008000;"><br></span><span style="color: #000000;">HWND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hWnd;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;WINAPI&nbsp;WinMain&nbsp;(HINSTANCE&nbsp;hInstance,&nbsp;HINSTANCE&nbsp;hPrevInstance,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PSTR&nbsp;szCmdLine,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;iCmdShow)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;TCHAR&nbsp;szAppName[]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;TEXT(</span><span style="color: #000000;">"</span><span style="color: #000000;">生长者消费者</span><span style="color: #000000;">"</span><span style="color: #000000;">)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;MSG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;WNDCLASS&nbsp;&nbsp;&nbsp;&nbsp;wndclass&nbsp;;<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.style&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CS_HREDRAW&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;CS_VREDRAW&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.lpfnWndProc&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;WndProc&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.cbClsExtra&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.cbWndExtra&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.hInstance&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;hInstance&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.hIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;LoadIcon&nbsp;(NULL,&nbsp;IDI_APPLICATION)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.hCursor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;LoadCursor&nbsp;(NULL,&nbsp;IDC_ARROW)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.hbrBackground</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(HBRUSH)&nbsp;GetStockObject&nbsp;(WHITE_BRUSH)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.lpszMenuName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;wndclass.lpszClassName</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;szAppName&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">RegisterClass&nbsp;(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">wndclass))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox&nbsp;(&nbsp;&nbsp;NULL,&nbsp;TEXT&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">This&nbsp;program&nbsp;requires&nbsp;Windows&nbsp;NT!</span><span style="color: #000000;">"</span><span style="color: #000000;">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;szAppName,&nbsp;MB_ICONERROR)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hWnd&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateWindow(&nbsp;szAppName,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TEXT&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">生长者消费者</span><span style="color: #000000;">"</span><span style="color: #000000;">),&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WS_OVERLAPPEDWINDOW,&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CW_USEDEFAULT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CW_USEDEFAULT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CW_USEDEFAULT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CW_USEDEFAULT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hInstance,&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ShowWindow&nbsp;(hWnd,&nbsp;iCmdShow)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;UpdateWindow&nbsp;(hWnd)&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ProduceAndConsume();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建生产者消费者线程、信号量、Mutex，并运行</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(GetMessage&nbsp;(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg,&nbsp;NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage&nbsp;(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage&nbsp;(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;EndProduceConsume();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)msg.wParam&nbsp;;<br>}<br><br><br>LRESULT&nbsp;CALLBACK&nbsp;WndProc&nbsp;(HWND&nbsp;hwnd,&nbsp;UINT&nbsp;message,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iXStart,iYStart;<br>&nbsp;&nbsp;&nbsp;&nbsp;HDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hdc&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;HBRUSH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hBrush;<br>&nbsp;&nbsp;&nbsp;&nbsp;PAINTSTRUCT&nbsp;&nbsp;&nbsp;&nbsp;ps&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;RECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rect;<br>&nbsp;&nbsp;&nbsp;&nbsp;MSG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">switch</span><span style="color: #000000;">&nbsp;(message)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;WM_CREATE:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;WM_FORCE_PAINT:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InvalidateRect(hWnd,&nbsp;NULL,&nbsp;TRUE);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(PeekMessage(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg,&nbsp;hWnd,&nbsp;WM_FORCE_PAINT,&nbsp;WM_FORCE_PAINT,&nbsp;PM_REMOVE))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;&nbsp;WM_PAINT:&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hdc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;BeginPaint&nbsp;(hwnd,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ps)&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetClientRect(hWnd,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">rect);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iXStart&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(rect.right</span><span style="color: #000000;">-</span><span style="color: #000000;">rect.left)</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">-</span><span style="color: #000000;">200</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iYStart&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(rect.bottom</span><span style="color: #000000;">-</span><span style="color: #000000;">rect.top)</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">-</span><span style="color: #000000;">10</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hBrush&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;SelectObject(hdc,&nbsp;(HBRUSH)GetStockObject(GRAY_BRUSH));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;iConsumerPointer;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(TRUE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rectangle(hdc,&nbsp;iXStart</span><span style="color: #000000;">+</span><span style="color: #000000;">iTemp</span><span style="color: #000000;">*</span><span style="color: #000000;">20</span><span style="color: #000000;">,&nbsp;iYStart,&nbsp;iXStart</span><span style="color: #000000;">+</span><span style="color: #000000;">(iTemp</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">)</span><span style="color: #000000;">*</span><span style="color: #000000;">20</span><span style="color: #000000;">,&nbsp;iYStart</span><span style="color: #000000;">+</span><span style="color: #000000;">20</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">++</span><span style="color: #000000;">iTemp&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;BUFFER_SIZE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(iTemp&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;iProducerPointer)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SelectObject(hdc,&nbsp;hBrush);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(TRUE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rectangle(hdc,&nbsp;iXStart</span><span style="color: #000000;">+</span><span style="color: #000000;">iTemp</span><span style="color: #000000;">*</span><span style="color: #000000;">20</span><span style="color: #000000;">,&nbsp;iYStart,&nbsp;iXStart</span><span style="color: #000000;">+</span><span style="color: #000000;">(iTemp</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">)</span><span style="color: #000000;">*</span><span style="color: #000000;">20</span><span style="color: #000000;">,&nbsp;iYStart</span><span style="color: #000000;">+</span><span style="color: #000000;">20</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">++</span><span style="color: #000000;">iTemp&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;BUFFER_SIZE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(iTemp&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;iConsumerPointer)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EndPaint&nbsp;(hwnd,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ps)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;WM_DESTROY:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostQuitMessage&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;DefWindowProc&nbsp;(hwnd,&nbsp;message,&nbsp;wParam,&nbsp;lParam)&nbsp;;<br>}<br><br>DWORD&nbsp;WINAPI&nbsp;ProducerThread(LPVOID&nbsp;pVoid)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iRandom;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(TRUE)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srand((unsigned)time(NULL));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iRandom&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;rand()</span><span style="color: #000000;">%</span><span style="color: #000000;">MAX_PRODUCE_COUNT;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(iRandom&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iRandom</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者申请iRandom个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iRandom;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(&nbsp;WAIT_OBJECT_0&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WaitForSingleObject(hProducerSemaphore,&nbsp;INFINITE)&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者生产iRandom个商品</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iProducerPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;iProducerPointer</span><span style="color: #000000;">+</span><span style="color: #000000;">iRandom;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(iProducerPointer</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">BUFFER_SIZE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iProducerPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;iProducerPointer</span><span style="color: #000000;">-</span><span style="color: #000000;">BUFFER_SIZE;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(hWnd,&nbsp;WM_FORCE_PAINT,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(SLEEP_TIME);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">生产者生产了iRandom个商品，消费者有更多的商品消费了；所以为消费者释放iRandom个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(ReleaseSemaphore(hConsumerSemaphore,&nbsp;(</span><span style="color: #0000ff;">long</span><span style="color: #000000;">)iRandom,&nbsp;NULL));<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br><br>DWORD&nbsp;WINAPI&nbsp;ConsumerThread(LPVOID&nbsp;pVoid)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(TRUE)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者申请到Semaphore和Mutex后，才能消费</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(&nbsp;WAIT_OBJECT_0&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WaitForSingleObject(hConsumerSemaphore,&nbsp;INFINITE)&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(&nbsp;WAIT_OBJECT_0&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WaitForSingleObject(hConsumerMutex,&nbsp;INFINITE)&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者消费一个商品</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iConsumerPointer</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(iConsumerPointer</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">BUFFER_SIZE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iConsumerPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(hWnd,&nbsp;WM_FORCE_PAINT,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(SLEEP_TIME</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者释放Mutex</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(ReleaseMutex(hConsumerMutex));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">消费者消费了一个商品，buffer中多了一个空闲位置，为生产者释放一个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(ReleaseSemaphore(hProducerSemaphore,&nbsp;(</span><span style="color: #0000ff;">long</span><span style="color: #000000;">)</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;NULL));<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;ProduceAndConsume()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;dwThreadID;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;iProducerPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;iConsumerPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hProducerSemaphore&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateSemaphore(NULL,&nbsp;BUFFER_SIZE,&nbsp;BUFFER_SIZE,&nbsp;NULL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建生产者信号量，初始有20个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hConsumerSemaphore&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateSemaphore(NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;BUFFER_SIZE,&nbsp;NULL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">创建消费者信号量，初始有0个资源</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hConsumerMutex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateMutex(NULL,&nbsp;FALSE,&nbsp;NULL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">创建消费者Mutex</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;hProducerThread&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;ProducerThread,&nbsp;NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">dwThreadID);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">CONSUMER_COUNT;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hConsumersThread[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;ConsumerThread,&nbsp;NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">dwThreadID);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;EndProduceConsume()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(CloseHandle(hProducerSemaphore));<br>&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(CloseHandle(hConsumerSemaphore));<br>&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(CloseHandle(hConsumerMutex));<br>&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(CloseHandle(hProducerThread));<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">CONSUMER_COUNT;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(CloseHandle(hConsumersThread[i]));<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</span></div>
<br>     <img src ="http://www.cppblog.com/sixinquan/aggbug/109713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-03-15 01:22 <a href="http://www.cppblog.com/sixinquan/archive/2010/03/15/109713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WIN32多线程四 线程同步机制Mutex</title><link>http://www.cppblog.com/sixinquan/archive/2010/02/23/108290.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Tue, 23 Feb 2010 09:47:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/02/23/108290.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/108290.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/02/23/108290.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/108290.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/108290.html</trackback:ping><description><![CDATA[Mutex与CriticalSection相似，都为了处理多个线程对资源的访问。区别是：mutex是内核对象，锁住mutex需要花费更多的时间，mutex可以跨进程存在。没有任何线程拥有mutex，这个mutex处于未激发状态，线程通过调用WaitForXXX来获得此mutex；除非这个线程ReleaseMutex，否则其他线程都不能获得这个mutex的拥有权。<br>Mutex可以用来解决哲学家就餐问题：让每个哲学家要么获得两根筷子，要么一跟筷子都不获得。哲学家就餐问题中，筷子相当于mutex，每个哲学家要么获得两个mutex，要么一个都不获得。这样就可以防止死锁的发生。<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">/*</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;MTVERYFY.h&nbsp;&nbsp; &lt;&lt;Win32多线程程序设计&gt;&gt;作者提供的一个非常好用的宏<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #008000;"></span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">#pragma&nbsp;comment(&nbsp;lib,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">USER32</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">crtdbg.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;MTASSERT(a)&nbsp;_ASSERTE(a)</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;MTVERIFY(a)&nbsp;if&nbsp;(!(a))&nbsp;PrintError(#a,__FILE__,__LINE__,GetLastError())</span><span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">__inline&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PrintError(LPSTR&nbsp;linedesc,&nbsp;LPSTR&nbsp;filename,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;lineno,&nbsp;DWORD&nbsp;errnum)<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;LPSTR&nbsp;lpBuffer;<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;errbuf[</span><span style="color: #000000;">256</span><span style="color: #000000;">];<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">#ifdef&nbsp;_WINDOWS<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;modulename[MAX_PATH];<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#else</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;_WINDOWS</span><span style="color: #000000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;numread;<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;_WINDOWS</span><span style="color: #000000;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;FormatMessage(&nbsp;FORMAT_MESSAGE_ALLOCATE_BUFFER<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;FORMAT_MESSAGE_FROM_SYSTEM,<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errnum,<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LANG_NEUTRAL,<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPTSTR)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">lpBuffer,<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL&nbsp;);<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;wsprintf(errbuf,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\nThe&nbsp;following&nbsp;call&nbsp;failed&nbsp;at&nbsp;line&nbsp;%d&nbsp;in&nbsp;%s:\n\n</span><span style="color: #000000;">"</span><span style="color: #000000;"><br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;%s\n\nReason:&nbsp;%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;lineno,&nbsp;filename,&nbsp;linedesc,&nbsp;lpBuffer);<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">#ifndef&nbsp;_WINDOWS<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;WriteFile(GetStdHandle(STD_ERROR_HANDLE),&nbsp;errbuf,&nbsp;strlen(errbuf),&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">numread,&nbsp;FALSE&nbsp;);<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="color: #000000;">3000</span><span style="color: #000000;">);<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#else</span><span style="color: #000000;"><br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileName(NULL,&nbsp;modulename,&nbsp;MAX_PATH);<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(NULL,&nbsp;errbuf,&nbsp;modulename,&nbsp;MB_ICONWARNING</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_OK</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_TASKMODAL</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_SETFOREGROUND);<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">MTVERIFY.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;NUM_PHIL&nbsp;&nbsp;&nbsp;&nbsp;5</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">HANDLE&nbsp;gChopSticks[NUM_PHIL]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{INVALID_HANDLE_VALUE};&nbsp; </span><span style="color: #000000;"></span><span style="color: #008000;">//Mutex句柄，用来表示</span><span style="color: #008000;">筷子，即哲学家们争取的资源</span><span style="color: #000000;"></span><br><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">static</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> flag&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID);&nbsp; </span><span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">线程函数，每个线程代表一个哲学家，哲学家们来争夺筷子(即Mutex)资源</span><br><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hPhil[NUM_PHIL];<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NUM_PHIL;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;gChopSticks[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateMutex(NULL,&nbsp;FALSE,&nbsp;NULL)&nbsp;);<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;hPhil[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;ThreadFunc,&nbsp;(LPVOID)i,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;NULL)&nbsp;);<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="color: #000000;">20000</span><span style="color: #000000;">); </span><span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;"> 主线程睡眠20000ms,这段时间内，所有哲学家想吃饭的时候，争夺筷子资源</span><br><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;flag&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp; </span><span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;"> 标志置为0，让所有线程都正常退出</span><br><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp; <br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;WAIT_OBJECT_0&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WaitForMultipleObjects(NUM_PHIL,&nbsp;hPhil,&nbsp;TRUE,&nbsp;INFINITE)&nbsp;);<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NUM_PHIL;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;CloseHandle(gChopSticks[i])&nbsp;);<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;CloseHandle(hPhil[i])&nbsp;);<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;n)<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;rc;<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;myChopSticks[</span><span style="color: #000000;">2</span><span style="color: #000000;">];<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nIndex&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)n;<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(&nbsp;flag </span><span style="color: #000000;"></span><span style="color: #000000;"></span><span style="color: #000000;"></span><span style="color: #000000;"> )<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myChopSticks[</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;gChopSticks[nIndex</span><span style="color: #000000;">%</span><span style="color: #000000;">NUM_PHIL];<br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myChopSticks[</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;gChopSticks[(nIndex</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">)</span><span style="color: #000000;">%</span><span style="color: #000000;">NUM_PHIL];<br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;WAIT_OBJECT_0&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WaitForMultipleObjects(</span><span style="color: #000000;">2</span><span style="color: #000000;">,&nbsp;myChopSticks,&nbsp;TRUE,&nbsp;INFINITE)&nbsp;); </span><span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">哲学家等待他身边的两根筷子</span><br><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Philosopher&nbsp;#&nbsp;%d&nbsp;is&nbsp;eating\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;nIndex);<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="color: #000000;">50</span><span style="color: #000000;">);<br></span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReleaseMutex(myChopSticks[</span><span style="color: #000000;">0</span><span style="color: #000000;">]);<br></span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReleaseMutex(myChopSticks[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br></span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(DWORD)n;<br></span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>     <img src ="http://www.cppblog.com/sixinquan/aggbug/108290.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-02-23 17:47 <a href="http://www.cppblog.com/sixinquan/archive/2010/02/23/108290.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WIN32多线程三 线程同步机制Critical Section</title><link>http://www.cppblog.com/sixinquan/archive/2010/02/23/108289.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Tue, 23 Feb 2010 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/02/23/108289.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/108289.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/02/23/108289.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/108289.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/108289.html</trackback:ping><description><![CDATA[就是通常说的"锁"，多线程对同一份资源的同步控制，经常用Critical Section，用来锁住一份资源，以免多个线程"同时"访问一份资源。通过下面<br>4个函数来使用InitializeCriticalSection&nbsp; EnterCriticalSection&nbsp; LeaveCriticalSection&nbsp; DeleteCriticalSection来使用。<br><br>需要注意的地方：不要长时间的锁住一份资源，不要在锁住资源而没有释放的时候调用Sleep WaitXXX。如果进入CriticalSection的那个线程当掉了<br>，而没有离开CriticalSection，系统没有办法将其清掉，因为它不是内核对象，不归操作系统管理。<br><br>另一个注意地方：每次调用EnterCriticalSection，会使该CriticalSection的引用计数加1，一个线程可以多次调用EnterCriticalSection，使计数<br>减1。调用了多少次EnterCriticalSection，就应该调用多少次LeaveCriticalSection。<br><br>下面是个考虑了多线程的链表的例子，但也不是完全多线程安全。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Node<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;data;<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">next;<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;List<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;List();<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">List();<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;InsertNode(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode,&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNewNode);<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;AddHead(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode);<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">Next(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode);<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Init();<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Destroy();<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">m_pHead;<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CRITICAL_SECTION&nbsp;m_cs;<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">};</span></div>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;"> 1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">list.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">List::List()<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;InitializeCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Init();<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">List::</span><span style="color: #000000;">~</span><span style="color: #000000;">List()<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Destroy();<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DeleteCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;List::Init()<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;m_pHead&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;List::Destroy()<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode;<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pTemp;<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pNode&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m_pHead;<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(pNode)<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pTemp = pNode;<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode </span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next;<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pTemp;<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;List::InsertNode(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode,&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNewNode)<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next)<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNewNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next;<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNewNode;<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNewNode;<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;List::AddHead(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode)<br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m_pHead;<br></span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;m_pHead&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNode;<br></span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">Node</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;List::Next(Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode)<br></span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">60</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pNext;<br></span><span style="color: #008080;">61</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">62</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">63</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pNext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next;<br></span><span style="color: #008080;">64</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m_cs);<br></span><span style="color: #008080;">65</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">66</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pNext;<br></span><span style="color: #008080;">67</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;"></span><span style="color: #000000;"></span><span style="color: #008080;"></span><span style="color: #000000;"></span><span style="color: #0000ff;"></span><span style="color: #000000;"></span><span style="color: #008080;"></span><span style="color: #000000;"></span><span style="color: #008080;"></span><span style="color: #000000;"></span><span style="color: #0000ff;"></span><span style="color: #000000;"></span><span style="color: #000000;"></span><span style="color: #000000;"></span><span style="color: #008080;"></span><span style="color: #000000;"></span></div>
<br> <img src ="http://www.cppblog.com/sixinquan/aggbug/108289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-02-23 17:44 <a href="http://www.cppblog.com/sixinquan/archive/2010/02/23/108289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WIN32多线程二 用WaitXXX函数等待线程结束</title><link>http://www.cppblog.com/sixinquan/archive/2010/02/22/108229.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Mon, 22 Feb 2010 07:45:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/02/22/108229.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/108229.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/02/22/108229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/108229.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/108229.html</trackback:ping><description><![CDATA[等待线程结束的更好方法是调用API WaitForSigleObject和WaitForMultipleObjects。前者用于等待一个线程由未激发状态变为激发状态，后者用于等待多个线程中全部或多个中的一个由未激发状态变为激发状态。对线程内核对象而言，如果线程在运行，则是未激发状态；如果线程已经退出，则是激发状态。不同内核对象的激发、未激发状态含义有所不同。<br><br>DWORD WINAPI WaitForSingleObject(<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE hHandle,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //等待的内核对象句柄<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwMilliseconds&nbsp;&nbsp;&nbsp; //等待的超时时间<br>);<br>函数失败，返回WAIT_FAILED；<br>等待对象变为激发状态，返回WAIT_OBJECT_O；<br>等待超时，返回WAIT_TIMEOUT；<br>一个拥有mutex的线程结束前，没有释放掉mutex，则返回WAIT_ABANDONED.<br><br>DWORD WINAPI WaitForMultipleObjects(<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD nCount,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //等待内核对象个数<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const HANDLE* lpHandles,//内核对象数组<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bWaitAll,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //是否等待所有内核对象，还是等待其中一个变为激发状态就返回<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwMilliseconds&nbsp;&nbsp;&nbsp; //等待的超时时间<br>);<br>函数失败，返回WAIT_FAILED；<br>等待超时，返回WAIT_TIMEOUT；<br>bWaitAll为TRUE，所有对象变为激发状态，返回WAIT_OBJECT_O；<br>bWaitAll为FALSE，返回值减去WAIT_OBJECT_O的值就是变为激发状态内核对象在数组中的索引；<br>如果内核对象中有mutex，返回值可能在WAIT_ABANDONED到WAIT_ABANDONED+nCount-1。<br><br>下面是个&lt;&lt;WIN32多线程程序设计&gt;&gt;中用WaitForMultipleObjects实现的简单的线程池的例子，3个线程来完成6个任务。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">/*</span><span style="color: #008000;"><br>&nbsp;*&nbsp;MTVERYFY.h<br></span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>#pragma&nbsp;comment(&nbsp;lib,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">USER32</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;)<br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">crtdbg.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;MTASSERT(a)&nbsp;_ASSERTE(a)</span><span style="color: #000000;"><br><br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;MTVERIFY(a)&nbsp;if&nbsp;(!(a))&nbsp;PrintError(#a,__FILE__,__LINE__,GetLastError())</span><span style="color: #000000;"><br><br>__inline&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PrintError(LPSTR&nbsp;linedesc,&nbsp;LPSTR&nbsp;filename,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;lineno,&nbsp;DWORD&nbsp;errnum)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;LPSTR&nbsp;lpBuffer;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;errbuf[</span><span style="color: #000000;">256</span><span style="color: #000000;">];<br>#ifdef&nbsp;_WINDOWS<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;modulename[MAX_PATH];<br></span><span style="color: #0000ff;">#else</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;_WINDOWS</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;numread;<br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;_WINDOWS</span><span style="color: #000000;"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;FormatMessage(&nbsp;FORMAT_MESSAGE_ALLOCATE_BUFFER<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;FORMAT_MESSAGE_FROM_SYSTEM,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errnum,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LANG_NEUTRAL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPTSTR)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">lpBuffer,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;wsprintf(errbuf,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\nThe&nbsp;following&nbsp;call&nbsp;failed&nbsp;at&nbsp;line&nbsp;%d&nbsp;in&nbsp;%s:\n\n</span><span style="color: #000000;">"</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;%s\n\nReason:&nbsp;%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;lineno,&nbsp;filename,&nbsp;linedesc,&nbsp;lpBuffer);<br>#ifndef&nbsp;_WINDOWS<br>&nbsp;&nbsp;&nbsp;&nbsp;WriteFile(GetStdHandle(STD_ERROR_HANDLE),&nbsp;errbuf,&nbsp;strlen(errbuf),&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">numread,&nbsp;FALSE&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="color: #000000;">3000</span><span style="color: #000000;">);<br></span><span style="color: #0000ff;">#else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileName(NULL,&nbsp;modulename,&nbsp;MAX_PATH);<br>&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(NULL,&nbsp;errbuf,&nbsp;modulename,&nbsp;MB_ICONWARNING</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_OK</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_TASKMODAL</span><span style="color: #000000;">|</span><span style="color: #000000;">MB_SETFOREGROUND);<br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">MTVERIFY.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;THREAD_POOL_SIZE&nbsp;&nbsp;3</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;NUM_TASKS&nbsp;&nbsp;&nbsp;&nbsp;6</span><span style="color: #000000;"><br><br>DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID);<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;hThreads[THREAD_POOL_SIZE];<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slot&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;dwThreadId;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;rc;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NUM_TASKS;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;i&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;THREAD_POOL_SIZE&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;WaitForMultipleObjects(THREAD_POOL_SIZE,&nbsp;hThreads,&nbsp;FALSE,&nbsp;INFINITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slot&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;rc&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;WAIT_OBJECT_0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">slot&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;slot</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">THREAD_POOL_SIZE&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Slot&nbsp;%d&nbsp;terminated.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,slot);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;CloseHandle(hThreads[slot])&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;hThreads[slot</span><span style="color: #000000;">++</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;ThreadFunc,&nbsp;(LPVOID)slot,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">dwThreadId)&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Launched&nbsp;thread&nbsp;#%d&nbsp;(slot&nbsp;%d).\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;i,&nbsp;slot);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;WaitForMultipleObjects(THREAD_POOL_SIZE,&nbsp;hThreads,&nbsp;TRUE,&nbsp;INFINITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;WAIT_OBJECT_0</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">rc&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;rc</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">WAIT_OBJECT_0</span><span style="color: #000000;">+</span><span style="color: #000000;">THREAD_POOL_SIZE&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(&nbsp;slot</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;slot</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">THREAD_POOL_SIZE;&nbsp;slot</span><span style="color: #000000;">++</span><span style="color: #000000;">&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MTVERIFY(&nbsp;CloseHandle(hThreads[slot])&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;EXIT_SUCCESS;<br>}<br><br><br>DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;n)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;srand(&nbsp;GetTickCount()&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(&nbsp;(rand()</span><span style="color: #000000;">%</span><span style="color: #000000;">10</span><span style="color: #000000;">)</span><span style="color: #000000;">*</span><span style="color: #000000;">800</span><span style="color: #000000;">+</span><span style="color: #000000;">500</span><span style="color: #000000;">&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Slot&nbsp;%d&nbsp;idle.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;n);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(DWORD)n;<br>}</span></div>
<br><img src ="http://www.cppblog.com/sixinquan/aggbug/108229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-02-22 15:45 <a href="http://www.cppblog.com/sixinquan/archive/2010/02/22/108229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WIN32多线程一 用WIN32 API创建和结束线程</title><link>http://www.cppblog.com/sixinquan/archive/2010/02/22/108202.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Mon, 22 Feb 2010 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/02/22/108202.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/108202.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/02/22/108202.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/108202.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/108202.html</trackback:ping><description><![CDATA[Win32中，内核对象属于WINDOWS的，而不属于进程。进程对象、线程对象、文件对象、文件映射对象、事件对象、互斥量对象等都属于内核对象。WIN32中一般通过CreateXXXX来创建内核对象，返回一个内核对象的句柄，进程不能直接操作内核对象，只能通过该句柄来访问内核对象。内核对象有一个使用计数，一个进程的内核对象句柄表中引用了某个内核对象，该内核对象的使用计数就递增1，该进程调用CloseHandle时，引用计数递减，当引用计数为0时，内核对象被销毁，当进程退出时，进程所引用内核对象的引用计数都递减1。<br><br>线程也是内核对象，当创建一个线程时，默认引用计数是2。调用CloseHandle时，线程引用计数下降1；当线程结束时，引用计数再下降1。仅仅调用CloseHandle并不能保证线程结束。利用这个特点，我们可以在调用CloseHandle前用GetExitCodeThread获得线程的结束代码，如果线程是STILL_ACTIVE状态，表示线程尚未结束。下面是一个能保证线程正常结束例子:<br><br>不过例子中等待线程结束的方法非常笨，用一个for循环不断检测线程状态，如果两个线程都结束了，才跳出循环，更好的方法是WaitForSigleObject，后面介绍。<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">/*</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;ExitCode.c<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #008000;">&nbsp;*<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;Sample&nbsp;code&nbsp;for&nbsp;"Multithreading&nbsp;Applications&nbsp;in&nbsp;Win32"<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;This&nbsp;is&nbsp;from&nbsp;Chapter&nbsp;2,&nbsp;Listing&nbsp;2-2<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #008000;">&nbsp;*<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;Start&nbsp;two&nbsp;threads&nbsp;and&nbsp;try&nbsp;to&nbsp;exit<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;when&nbsp;the&nbsp;user&nbsp;presses&nbsp;a&nbsp;key.<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #008000;">&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;WIN32_LEAN_AND_MEAN</span><span style="color: #000000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">conio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID);<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThrd1;<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThrd2;<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;exitCode1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;exitCode2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;threadId;<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hThrd1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThreadFunc,<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPVOID)</span><span style="color: #000000;">1</span><span style="color: #000000;">,<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">threadId&nbsp;);<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(hThrd1)<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;1&nbsp;launched\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hThrd2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateThread(NULL,<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThreadFunc,<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPVOID)</span><span style="color: #000000;">2</span><span style="color: #000000;">,<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">threadId&nbsp;);<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(hThrd2)<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;2&nbsp;launched\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Keep&nbsp;waiting&nbsp;until&nbsp;both&nbsp;calls&nbsp;to<br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;GetExitCodeThread&nbsp;succeed&nbsp;AND<br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;neither&nbsp;of&nbsp;them&nbsp;returns&nbsp;STILL_ACTIVE.<br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;This&nbsp;method&nbsp;is&nbsp;not&nbsp;optimal&nbsp;-&nbsp;we'll<br></span><span style="color: #008080;">50</span>&nbsp;<span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;see&nbsp;the&nbsp;correct&nbsp;way&nbsp;in&nbsp;Chapter&nbsp;3.</span><span style="color: #008000;"><br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(;;)<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Press&nbsp;any&nbsp;key&nbsp;to&nbsp;exit..\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getch();<br></span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetExitCodeThread(hThrd1,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">exitCode1);<br></span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetExitCodeThread(hThrd2,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">exitCode2);<br></span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;exitCode1&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;STILL_ACTIVE&nbsp;)<br></span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;1&nbsp;is&nbsp;still&nbsp;running!</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">60</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;exitCode2&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;STILL_ACTIVE&nbsp;)<br></span><span style="color: #008080;">61</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;2&nbsp;is&nbsp;still&nbsp;running!</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">62</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;exitCode1&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;STILL_ACTIVE<br></span><span style="color: #008080;">63</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;exitCode2&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;STILL_ACTIVE&nbsp;)<br></span><span style="color: #008080;">64</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br></span><span style="color: #008080;">65</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">66</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">67</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hThrd1);<br></span><span style="color: #008080;">68</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hThrd2);<br></span><span style="color: #008080;">69</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">70</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;1&nbsp;returned&nbsp;%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;exitCode1);<br></span><span style="color: #008080;">71</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Thread&nbsp;2&nbsp;returned&nbsp;%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;exitCode2);<br></span><span style="color: #008080;">72</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">73</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;EXIT_SUCCESS;<br></span><span style="color: #008080;">74</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">75</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">76</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">77</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">/*</span><span style="color: #008000;"><br></span><span style="color: #008080;">78</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;Take&nbsp;the&nbsp;startup&nbsp;value,&nbsp;do&nbsp;some&nbsp;simple&nbsp;math&nbsp;on&nbsp;it,<br></span><span style="color: #008080;">79</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;and&nbsp;return&nbsp;the&nbsp;calculated&nbsp;value.<br></span><span style="color: #008080;">80</span>&nbsp;<span style="color: #008000;">&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #008080;">81</span>&nbsp;<span style="color: #000000;">DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;n)<br></span><span style="color: #008080;">82</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">83</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Sleep((DWORD)n</span><span style="color: #000000;">*</span><span style="color: #000000;">1000</span><span style="color: #000000;">*</span><span style="color: #000000;">2</span><span style="color: #000000;">);<br></span><span style="color: #008080;">84</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(DWORD)n&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10</span><span style="color: #000000;">;<br></span><span style="color: #008080;">85</span>&nbsp;<span style="color: #000000;">}</span></div>
<br>线程也可以自己结束掉自己，方法是调用ExitThread。尽量不在主线程中调用ExitTread，这样会强制其他线程终止，进程终止，而其他线程没有机会做清理工作。<br><br>     <img src ="http://www.cppblog.com/sixinquan/aggbug/108202.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-02-22 11:15 <a href="http://www.cppblog.com/sixinquan/archive/2010/02/22/108202.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WIN32串口通信类</title><link>http://www.cppblog.com/sixinquan/archive/2010/02/21/108139.html</link><dc:creator>sin</dc:creator><author>sin</author><pubDate>Sun, 21 Feb 2010 04:53:00 GMT</pubDate><guid>http://www.cppblog.com/sixinquan/archive/2010/02/21/108139.html</guid><wfw:comment>http://www.cppblog.com/sixinquan/comments/108139.html</wfw:comment><comments>http://www.cppblog.com/sixinquan/archive/2010/02/21/108139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sixinquan/comments/commentRss/108139.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sixinquan/services/trackbacks/108139.html</trackback:ping><description><![CDATA[串口的操作可以有两种操作方式：同步操作方式和重叠操作方式（又称为异步操作方式）。同步操作时，API函数会阻塞直到操作完成以后才能返回（在多线程方式中，虽然不会阻塞主线程，会阻塞串口读写线程）；而重叠操作方式，API函数会立即返回，操作在后台进行，避免线程的阻塞。下面介绍的是同步方式。WIN32串口编程一般分为:打开串口、配置串口、读写串口、关闭串口。<br><br>打开串口<br>WIN32将各种设备、端口都抽象为文件，提供统一的编程接口，打开串口也就是打开文件，通过API CreateFile来完成。<br>HANDLE WINAPI CreateFile(<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpFileName,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //文件名，串口通讯中位"COM1" "COM2"等<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwDesiredAccess,&nbsp;&nbsp;&nbsp; //访问权限，可以是读、写或读写并行<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwShareMode,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //共享模式，串口通讯中一般为0<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpSecurityAttributes,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //安全属性，缺省为NULL<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwCreationDisposition,//创建标志，对串口操作必须为OPEN_EXISTING<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwFlagsAndAttributes,&nbsp;&nbsp;&nbsp; //属性，同步或是异步方式<br>&nbsp; __in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE hTemplateFile&nbsp;&nbsp;&nbsp; //当打开已存在的文件时，忽略此参数<br>);<br><br>配置串口<br>在打开通讯设备句柄后，常常需要对串口进行一些初始化配置工作。这需要通过一个DCB结构来进行。在查询或配置串口的属性时，都要用DCB结构来作为缓冲区。一般用CreateFile打开串口后，可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置，应该先修改DCB结构，再调用SetCommState函数设置串口。除设置DCB外，还要设置串口缓冲区大小，通过API SetupComm完成；设置超时时间，通过SetCommTimeouts完成；开始读写串口前，还要通过API PurgeComm来清空缓冲区。这几个API详细信息可查看MSDN,不同情况设置参数可能不一样。<br><br>涉及的结构体有DCB 和 COMMTIMEOUTS,详细说明可查看MSDN。<br><br>typedef struct _DCB{&nbsp;&nbsp;&nbsp; //仅列出几个常用的配置项:<br>&nbsp;&nbsp; &#8230;&#8230;&#8230;<br>&nbsp;&nbsp; DWORD BaudRate; &nbsp;&nbsp;&nbsp; //波特率<br>&nbsp;&nbsp; DWORD fParity; &nbsp;&nbsp;&nbsp;&nbsp; //指定是否允许奇偶校验。若此成员为1，允许奇偶校验检查<br>&nbsp;&nbsp; BYTE ByteSize; &nbsp;&nbsp;&nbsp;&nbsp; //通信字节位数，4—8<br>&nbsp;&nbsp; BYTE Parity; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //指定奇偶校验方法。此成员可以有下列值：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //EVENPARITY 偶校验&nbsp;&nbsp;&nbsp;&nbsp; NOPARITY 无校验<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //MARKPARITY 标记校验&nbsp;&nbsp; ODDPARITY 奇校验<br>&nbsp;&nbsp; BYTE StopBits; &nbsp;&nbsp;&nbsp;&nbsp; //指定停止位的位数。此成员可以有下列值：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //ONESTOPBIT&nbsp;&nbsp; 1位停止位&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //TWOSTOPBITS&nbsp; 2位停止<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //ONE5STOPBITS 1.5位停止位<br>&nbsp;&nbsp; &#8230;&#8230;&#8230;<br>&nbsp; } DCB;<br><br>typedef struct _COMMTIMEOUTS {&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; DWORD ReadIntervalTimeout; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //读间隔超时<br>&nbsp;&nbsp;&nbsp; DWORD ReadTotalTimeoutMultiplier; &nbsp;&nbsp; //读时间系数<br>&nbsp;&nbsp;&nbsp; DWORD ReadTotalTimeoutConstant; &nbsp;&nbsp;&nbsp;&nbsp; //读时间常量<br>&nbsp;&nbsp;&nbsp; DWORD WriteTotalTimeoutMultiplier; &nbsp; //写时间系数<br>&nbsp;&nbsp;&nbsp; DWORD WriteTotalTimeoutConstant; &nbsp;&nbsp;&nbsp; //写时间常量<br>} COMMTIMEOUTS,*LPCOMMTIMEOUTS;<br><br>读写串口<br>跟读写普通文件一样，通过ReadFile 和 WriteFile来完成。如果有多个线程访问串口的话，要做好不同线程的同步，简单的方法可通过WIN32的关键代码段来同步,避免多个线程同时访问串口。<br><br>关闭串口<br>利用API CloseHandle关闭即可。<br><br>上面只是简单介绍了WIN32串口编程，更多具体的信息如DCB的设置、串口超时设置、缓冲区大小设置，可能需要在具体调试中根据情况来设置。特别重要的一点是多线程的同步问题，特别在串口数据传输速度很快的时候，需要仔细设计。<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CCommPort&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CCommPort();<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">CCommPort();<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Open(&nbsp;LPCTSTR&nbsp;szPort,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nBaud,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nDataBit,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nStopBit,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nParity&nbsp;);<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Close();<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Write(&nbsp;LPVOID&nbsp;pBuf,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nSize,&nbsp;DWORD</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;dwWritten&nbsp;);<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Read(&nbsp;LPVOID&nbsp;pBuf,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nSize,&nbsp;DWORD</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;dwReaded&nbsp;);<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Clear();<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;IsOpen();&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_handle;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CRITICAL_SECTION&nbsp;m_cs;<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">};</span></div>
<br>  <img src ="http://www.cppblog.com/sixinquan/aggbug/108139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sixinquan/" target="_blank">sin</a> 2010-02-21 12:53 <a href="http://www.cppblog.com/sixinquan/archive/2010/02/21/108139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>