﻿<?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++博客-    Update 牌...@ Blog-随笔分类-进程和线程</title><link>http://www.cppblog.com/Lee7/category/5944.html</link><description>  当华美的叶片落尽，生命的脉络才历历可见。 －－ 聂鲁达    
</description><language>zh-cn</language><lastBuildDate>Mon, 18 Aug 2008 13:50:47 GMT</lastBuildDate><pubDate>Mon, 18 Aug 2008 13:50:47 GMT</pubDate><ttl>60</ttl><item><title>VC 多线程编程 </title><link>http://www.cppblog.com/Lee7/archive/2008/08/15/58952.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Fri, 15 Aug 2008 09:18:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/08/15/58952.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/58952.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/08/15/58952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/58952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/58952.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:  进程和线程都是操作系统的概念。进程是应用程序的执行实例，每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成，进程在运行过程中创建的资源随着进程的终止而被销毁，所使用的系统资源在进程终止时被释放或关闭。<br>　　线程是进程内部的一个执行单元。系统创建好进程后，实际上就启动执行了该进程的主执行线程，主执行线程以函数地址形式，比如说main或WinMain函数，将程序的启动点提供给Windows系统。主执行线程终止了，进程也就随之终止。<br>　　每一个进程至少有一个主执行线程，它无需由用户去主动创建，是由系统自动创建的。用户根据需要在应用程序中创建其它线程，多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中，共同使用这些虚拟地址空间、全局变量和系统资源，所以线程间的通讯非常方便，多线程技术的应用也较为广泛。&nbsp;&nbsp;<a href='http://www.cppblog.com/Lee7/archive/2008/08/15/58952.html'>阅读全文</a><img src ="http://www.cppblog.com/Lee7/aggbug/58952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-08-15 17:18 <a href="http://www.cppblog.com/Lee7/archive/2008/08/15/58952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC全局函数::AfxBeginThread </title><link>http://www.cppblog.com/Lee7/archive/2008/05/23/50908.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Fri, 23 May 2008 14:56:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/05/23/50908.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/50908.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/05/23/50908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/50908.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/50908.html</trackback:ping><description><![CDATA[函数功能描述:创建新的线程<br><br>函数原型：<br>CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = <br>THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES <br>lpSecurityAttrs = NULL );<br><br>CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, <br>UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );<br><br>返回值：<br>指向新创建的线程对象。<br><br>参数：<br>pfnThreadProc：工作线程的函数指针，不可以为空。并且工作线程的函数必须如此声明：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT MyControllingFunction( LPVOID pParam );<br>pThreadClass： 从CWinThread类继承来的对象的RUNTIME_CLASS指针。<br>pParam:　　　　传递给工作线程函数pfnThreadProc的参数。<br>nPriority：　　线程的优先级。如果为0，则与创建它的线程优先级相同。可以通过参考Win32 Programmer&#8217;s <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reference中的SetThreadPriority得到所有可用的优先级列表和描述。<br>nStackSize：　 以字节为单位指定新线程的堆栈大小。如果为0，则与创建它的线程的堆栈大小相同。<br>dwCreateFlags：指定一个额外的标志控制线程的产生。它可以包括下面两个值中的一个：<br><br>　　　　　　　 CREATE_SUSPENDED：以挂起模式开始线程，并且指定挂起次数.当调用ResumeThread时，这个&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 线程才会被执行。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; 　　　　　：创建之后，马上执行线程。<br>lpSecurityAttrs：指向SECURITY_ATTRIBUTES结构的指针，结构中指定了线程的安全属性。如果为NULL，则与&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建它的线程的安全属性相同。如果希望得到更多的有关SECURITY_ATTRIBUTES结构的信息,&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;请参考Win32 Programmer&#8217;s Reference。<br>注释：<br>调用这个函数创建一个新的线程。第一种形式的AfxBeginThread创建一个工作线程；第二种形式创建一个用户<br>接口线程。<br>AfxBeginThread创建一个新的CWinThread对象,调用它的CreateThread函数开始执行线程并且返回指向线程的指<br>针。Checks are made throughout the procedure to make sure all objects are deallocated properly <br>should any part of the creation fail. 终止线程，可以在线程函数中调用AfxEndThread, 或者从工作线程<br>的函数中返回。<br>了解更多的有关AfxBeginThread的信息，可以参考文章　Multithreading: Creating Worker Threads 和 <br>Multithreading: Creating User-Interface Threads in Visual C++ Programmer&#8217;s Guide.<br><br>参看：AfxGetThread<br><br>示例：<br>&nbsp;&nbsp;创建一个工作线程：<br>UINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WorkForce(LPVOID lpParameter);//线程函数声明<br>CWinThread&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pMyFirstWorker，*pMySecondWorker;<br>LPVOID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pParam = NULL;<br>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nPriority = THREAD_PRIORITY_ABOVE_NORMAL;//默认为THREAD_PRIORITY_NORMAL<br>UINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nStackSize = 0;//与创建它的线程堆栈大小相同<br>DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwCreateFlags = 0;//创建后立即执行<br>LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ;//与创建它的线程安全属性相同<br><br>pMyFirstWorker=AfxBeginThread( (AFX_THREADPROC)WorkForce, pParam, nPriority , nStackSize,<br>dwCreateFlags , lpSecurityAttrs);<br>pMySecondWorker=AfxBeginThread( (AFX_THREADPROC)WorkForce, pParam);//如果采用默认值<br><br>DWORD WINAPI WorkForce( LPVOID lpParameter&nbsp;&nbsp; // 线程所需参数，可以通过它传递数据)<br>{<br>return 0;//什么不做<br>}
<p>&nbsp;</p>
<p>CWinThread* AfxBeginThread(<br>&nbsp;&nbsp; CRuntimeClass* pThreadClass,<br>&nbsp;&nbsp; int nPriority = THREAD_PRIORITY_NORMAL,<br>&nbsp;&nbsp; UINT nStackSize = 0,<br>&nbsp;&nbsp; DWORD dwCreateFlags = 0,<br>&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL <br>);</p>
<p>参数说明:<br>pfnThreadProc:线程函数的地址,该参数不能设置为NULL,线程函数必须定义成全局函数或者类的静态成员函数<br>例如:<br>UINT myThreadFunc(LPVOID lparam)<br>或者<br>class A<br>{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static UINT __stdcall myThreadFunc(LPVOID lparam);<br>}<br>之所以要定义成类的静态成员函数,是因为类的静态成员函数不属于某个类对象,这样在调用函数<br>的时候就不用传递一个额外的this指针.</p>
<p>pThreadClass:指向从CWinThread派生的子类对象的RUNTIME_CLASS</p>
<p>pParam:要传递给线程函数的参数</p>
<p>nPriority:要启动的线程的优先级,默认优先级为THREAD_PRIORITY_NORMAL(普通优先级),关于线程<br>&nbsp;优先级的详细说明请参考Platform SDK SetThreadPriority函数说明</p>
<p>nStackSize:新线程的堆栈大小,如果设置为0,则使用默认大小,在应用程序中一般情况下线程的默认堆栈大小<br>&nbsp;为1M</p>
<p>dwCreateFlags:线程创建标志,该参数可以指定为下列标志<br>&nbsp;CREATE_SUSPENDED:以挂起方式启动线程,如果你在线程启动之前想初始化一些CWinThread类中的一些成员变量<br>&nbsp;比如:m_bAutoDelete或者你的派生类中的成员变量,当初始化完成之后,你可以使用CWinThread类的ResumeThread<br>&nbsp;成员函数来恢复线程的运行<br>&nbsp;如果把该标志设置为0,则表示立即启动线程<br>lpSecurityAttrs:指向安全描述符的指针,如果使用默认的安全级别只要讲该参数设置为NULL就可以了!</p>
<p>上面就是AfxBeginThread函数的简单说明,我们在使用的时候一般情况下只要指定前两个参数,其他<br>参数使用默认值就可以.嗯,的确,使用起来是很简单,只要这个函数一被调用,就创建了一个线程.<br>但是大家有没有想过,AfxBeginThread函数究竟是如何启动的线程呢?它的内部是如何实现的呢?</p>
<p>下面我们就来看一下AfxBeginThread函数的内部实现</p>
<p>//启动worker线程<br>CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,<br>&nbsp;int nPriority, UINT nStackSize, DWORD dwCreateFlags,<br>&nbsp;LPSECURITY_ATTRIBUTES lpSecurityAttrs)<br>{<br>#ifndef _MT<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfnThreadProc;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pParam;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPriority;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nStackSize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwCreateFlags;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpSecurityAttrs;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;<br>#else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT(pfnThreadProc != NULL);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT_VALID(pThread);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!pThread-&gt;CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpSecurityAttrs))<br>&nbsp;&nbsp;&nbsp;&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;pThread-&gt;Delete();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VERIFY(pThread-&gt;SetThreadPriority(nPriority));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!(dwCreateFlags &amp; CREATE_SUSPENDED))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VERIFY(pThread-&gt;ResumeThread() != (DWORD)-1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return pThread;<br>#endif //!_MT)<br>}</p>
<p dir=ltr style="MARGIN-RIGHT: 0px">//启动UI线程<br>CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,<br>&nbsp;int nPriority, UINT nStackSize, DWORD dwCreateFlags,<br>&nbsp;LPSECURITY_ATTRIBUTES lpSecurityAttrs)<br>{<br>#ifndef _MT<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pThreadClass;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nPriority;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;nStackSize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwCreateFlags;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpSecurityAttrs;</p>
<p dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NULL;<br>#else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASSERT(pThreadClass != NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASSERT(pThreadClass-&gt;IsDerivedFrom(RUNTIME_CLASS(CWinThread)));</p>
<p dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CWinThread* pThread = (CWinThread*)pThreadClass-&gt;CreateObject();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pThread == NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxThrowMemoryException();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASSERT_VALID(pThread);</p>
<p dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pThread-&gt;m_pThreadParams = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!pThread-&gt;CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpSecurityAttrs))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pThread-&gt;Delete();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VERIFY(pThread-&gt;SetThreadPriority(nPriority));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(dwCreateFlags &amp; CREATE_SUSPENDED))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VERIFY(pThread-&gt;ResumeThread() != (DWORD)-1);</p>
<p dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return pThread;<br>#endif //!_MT<br>}</p>
<p>从上面的代码中可以看出AfxBeginThread所做的事情主要有以下几点:</p>
<p>1.在heap中配置一个新的CWinThread对象(worker线程)<br>代码如:CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);<br>调用CRuntimeClass结构中的CreateObject函数创建CWinThread对象<br>CWinThread* pThread = (CWinThread*)pThreadClass-&gt;CreateObject();<br>CRuntimeClass以及MFC相关类的内部实现,详情请参考<br>《深入浅出MFC》侯捷著</p>
<p>2.调用CWinThread::CreateThread()并设定属性,使线程以挂起状态产生<br>pThread-&gt;CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,lpSecurityAttrs);</p>
<p>3.设定线程的优先权<br>pThread-&gt;SetThreadPriority(nPriority);</p>
<p>4.调用CWinThread::ResumeThread<br>pThread-&gt;ResumeThread();<br><br>通过上面的说明,我想大家对该函数到底在内部都做了什么,应该有一个初步的了解了!<br></p>
<img src ="http://www.cppblog.com/Lee7/aggbug/50908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-05-23 22:56 <a href="http://www.cppblog.com/Lee7/archive/2008/05/23/50908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AfxBeginThread的基本用法</title><link>http://www.cppblog.com/Lee7/archive/2008/05/23/50907.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Fri, 23 May 2008 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/05/23/50907.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/50907.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/05/23/50907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/50907.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/50907.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPVOID pParam,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nPriority = THREAD_PRIORITY_NORMAL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNT nStackSize = 0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwCreateFlags = 0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );//用于创建工作者线程</font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>返回值: 一个指向新线程的线程对象<br>pfnThreadProc : 线程的入口函数,声明一定要如下: UINT MyThreadFunction( LPVOID pParam );<br>pParam : 传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程.<br>nPriority : 线程的优先级,一般设置为 0 .让它和主线程具有共同的优先级.<br>nStackSize : 指定新创建的线程的栈的大小.如果为 0,新创建的线程具有和主线程一样的大小的栈<br>dwCreateFlags : 指定创建线程以后,线程有怎么样的标志.可以指定两个值:<br>CREATE_SUSPENDED : 线程创建以后,会处于挂起状态,真到调用: ResumeThread<br>0 : 创建线程后就开始运行.<br>lpSecurityAttrs : 指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性.如果为 NULL , </font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>那么新创建的线程就具有和主线程一样的安全性.<br>如果要在线程内结束线程,可以在线程内调用 AfxEndThread.</font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>结束线程的两种方式<br>&nbsp;&nbsp;&nbsp;&nbsp; 当你在后台用线程来打印一些图形时.有时在打印一部分后,你希望可以停下来,那么此如何让线程停止呢.下</font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>面会详细的向你解释要结束线程的两种方式<br>&nbsp;&nbsp;&nbsp;&nbsp; 1 : 这是最简单的方式,也就是让线程函数执行完成,此时线程正常结束.它会返回一个值,一般0是成功结束,</font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>当然你可以定义自己的认为合适的值来代表线程成功执行.在线程内调用AfxEndThread将会直接结束线程,此时线</font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>程的一切资源都会被回收.<br>&nbsp;&nbsp;&nbsp;&nbsp; 2 : 如果你想让别一个线程B来结束线程A,那么,你就需要在这两个线程中传递信息.<br>不管是工作者线程还是界面线程,如果你想在线程结束后得到它的确结果,那么你可以调用: </font></p>
<p style="FONT-SIZE: 12px"><font face=Tahoma size=2>::GetExitCodeThread函数</font></p>
<img src ="http://www.cppblog.com/Lee7/aggbug/50907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-05-23 22:55 <a href="http://www.cppblog.com/Lee7/archive/2008/05/23/50907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线程与串行通信</title><link>http://www.cppblog.com/Lee7/archive/2008/01/07/40665.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 07 Jan 2008 15:40:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/01/07/40665.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/40665.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/01/07/40665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/40665.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/40665.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Windows是一个多任务操作系统。传统的Windows 3.x只能依靠应用程序之间的协同来实现协同式多任务，而Windows 95/NT实行的是抢先式多任务。<br><br>　　在Win 32(95/NT)中，每一个进程可以同时执行多个线程，这意味着一个程序可以同时完成多个任务。对于象通信程序这样既要进行耗时的工作，又要保持对用户输入响应的应用来说，使用多线程是最佳选择。当进程使用多个线程时，需要采取适当的措施来保持线程间的同步。<br><br>　　利用Win 32的重叠I/O操作和多线程特性，程序员可以编写出高效的通信程序。在这一讲的最后将通过一个简单的串行通信程序，向读者演示多线程和重叠I/O的编程技术。&nbsp;&nbsp;<a href='http://www.cppblog.com/Lee7/archive/2008/01/07/40665.html'>阅读全文</a><img src ="http://www.cppblog.com/Lee7/aggbug/40665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-01-07 23:40 <a href="http://www.cppblog.com/Lee7/archive/2008/01/07/40665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Overlapped I/O模型深入分析</title><link>http://www.cppblog.com/Lee7/archive/2008/01/07/40650.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 07 Jan 2008 14:47:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/01/07/40650.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/40650.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/01/07/40650.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/40650.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/40650.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:  Overlapped I/O也称Asynchronous  I/O，异步I/O模型。异步I/O和同步I/O不同，同步I/O时，程序被挂起，一直到I/O处理完，程序才能获得控制。异步I/O，调用一个函数告诉 OS，进行I/O操作，不等I/O结束就立即返回，继续程序执行，操作系统完成I/O之后，通知消息给你。Overlapped I/O只是一种模型，它可以由内核对象(hand)，事件内核对象(hEvent), 异步过程调用(apcs) 和完成端口(I/O completion)实现。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/Lee7/archive/2008/01/07/40650.html'>阅读全文</a><img src ="http://www.cppblog.com/Lee7/aggbug/40650.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-01-07 22:47 <a href="http://www.cppblog.com/Lee7/archive/2008/01/07/40650.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设备I/O之OVERLAPPED [转]</title><link>http://www.cppblog.com/Lee7/archive/2008/01/07/40647.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 07 Jan 2008 13:27:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2008/01/07/40647.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/40647.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2008/01/07/40647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/40647.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/40647.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: OVERLAPPED,顾名思义为重叠,乍一看会很奇怪,重叠?谁跟谁重叠？似乎在WIN32的Programming中没有这个概念呀?要讨论这个问题就要追溯到对设备I/O的访问中&nbsp;&nbsp;<a href='http://www.cppblog.com/Lee7/archive/2008/01/07/40647.html'>阅读全文</a><img src ="http://www.cppblog.com/Lee7/aggbug/40647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2008-01-07 21:27 <a href="http://www.cppblog.com/Lee7/archive/2008/01/07/40647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>