<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>中文 &#187; s030501408</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/s030501408/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/zh-cn/blogs</link>
	<description></description>
	<lastBuildDate>Sat, 26 May 2012 06:34:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>windows 多线程编程</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/07/05/windows/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/07/05/windows/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 09:49:42 +0000</pubDate>
		<dc:creator>s030501408</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[intel]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/07/05/windows/</guid>
		<description><![CDATA[一、MFC线程介绍 MFC中有两类线程，分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环，而用户界面线程有自己的消息队列和消息循环。 　　工作者线程没有消息机制，通常用来执行后台计算和维护任务，如冗长的计算过程，打印机的后台打印等。用户界面线程一般用于处理独立于其他线程执行之外的用户输入，响应用户及系统所产生的事件和消息等。但对于Win32的API编程而言，这两种线程是没有区别的，它们都只需线程的启动地址即可启动线程来执行任务。 　　在MFC中，一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行，该函数有两种重载形式，分别用于创建工作者线程和用户界面线程。两种重载函数原型和参数分别说明如下： (1) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam, nPriority=THREAD_PRIORITY_NORMAL, UINT nStackSize=0, DWORD dwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL); PfnThreadProc:指向工作者线程的执行函数的指针，线程函数原型必须声明如下： UINT ExecutingFunction(LPVOID pParam); 请注意，ExecutingFunction()应返回一个UINT类型的值，用以指明该函数结束的原因。一般情况下，返回0表明执行成功。 pParam：传递给线程函数的一个32位参数，执行函数将用某种方式解释该值。它可以是数值，或是指向一个结构的指针，甚至可以被忽略； nPriority：线程的优先级。如果为0，则线程与其父线程具有相同的优先级； nStackSize:线程为自己分配堆栈的大小，其单位为字节。如果nStackSize被设为0，则线程的堆栈被设置成与父线程堆栈相同大小； dwCreateFlags：如果为0，则线程在创建后立刻开始执行。如果为CREATE_SUSPEND，则线程在创建后立刻被挂起； lpSecurityAttrs：线程的安全属性指针，一般为NULL； (2) CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass, int nPriority=THREAD_PRIORITY_NORMAL, UINT nStackSize=0, DWORD dwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL); 　　pThreadClass 是指向 CWinThread 的一个导出类的运行时类对象的指针，该导出类定义了被创建的用户界面线程的启动、退出等；其它参数的意义同形式1。使用函数的这个原型生成的线程也有消息机制，在以后的例子中我们将发现同主线程的机制几乎一样。 下面我们对CWinThread类的数据成员及常用函数进行简要说明。 m_hThread：当前线程的句柄； m_nThreadID:当前线程的ID； m_pMainWnd：指向应用程序主窗口的指针 BOOL CWinThread::CreateThread(DWORD dwCreateFlags=0, UINT nStackSize=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL); 　　该函数中的dwCreateFlags、nStackSize、lpSecurityAttrs参数和API函数CreateThread中的对应参数有相同含义，该函数执行成功，返回非0值，否则返回0。 [...]]]></description>
			<content:encoded><![CDATA[<p>一、MFC线程介绍</p>
<p>MFC中有两类线程，分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环，而用户界面线程有自己的消息队列和消息循环。<br />
　　工作者线程没有消息机制，通常用来执行后台计算和维护任务，如冗长的计算过程，打印机的后台打印等。用户界面线程一般用于处理独立于其他线程执行之外的用户输入，响应用户及系统所产生的事件和消息等。但对于Win32的API编程而言，这两种线程是没有区别的，它们都只需线程的启动地址即可启动线程来执行任务。<br />
　　在MFC中，一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行，该函数有两种重载形式，分别用于创建工作者线程和用户界面线程。两种重载函数原型和参数分别说明如下：</p>
<p>(1) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,<br />
LPVOID pParam,<br />
nPriority=THREAD_PRIORITY_NORMAL,<br />
UINT nStackSize=0,<br />
DWORD dwCreateFlags=0,<br />
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);<br />
PfnThreadProc:指向工作者线程的执行函数的指针，线程函数原型必须声明如下：</p>
<p>UINT ExecutingFunction(LPVOID pParam);<br />
请注意，ExecutingFunction()应返回一个UINT类型的值，用以指明该函数结束的原因。一般情况下，返回0表明执行成功。</p>
<p>pParam：传递给线程函数的一个32位参数，执行函数将用某种方式解释该值。它可以是数值，或是指向一个结构的指针，甚至可以被忽略；<br />
nPriority：线程的优先级。如果为0，则线程与其父线程具有相同的优先级；<br />
nStackSize:线程为自己分配堆栈的大小，其单位为字节。如果nStackSize被设为0，则线程的堆栈被设置成与父线程堆栈相同大小；<br />
dwCreateFlags：如果为0，则线程在创建后立刻开始执行。如果为CREATE_SUSPEND，则线程在创建后立刻被挂起；<br />
lpSecurityAttrs：线程的安全属性指针，一般为NULL；<br />
(2) CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,<br />
int nPriority=THREAD_PRIORITY_NORMAL,<br />
UINT nStackSize=0,<br />
DWORD dwCreateFlags=0,<br />
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);<br />
　　pThreadClass 是指向 CWinThread 的一个导出类的运行时类对象的指针，该导出类定义了被创建的用户界面线程的启动、退出等；其它参数的意义同形式1。使用函数的这个原型生成的线程也有消息机制，在以后的例子中我们将发现同主线程的机制几乎一样。</p>
<p>下面我们对CWinThread类的数据成员及常用函数进行简要说明。</p>
<p>m_hThread：当前线程的句柄；<br />
m_nThreadID:当前线程的ID；<br />
m_pMainWnd：指向应用程序主窗口的指针<br />
BOOL CWinThread::CreateThread(DWORD dwCreateFlags=0,<br />
UINT nStackSize=0,<br />
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);<br />
　　该函数中的dwCreateFlags、nStackSize、lpSecurityAttrs参数和API函数CreateThread中的对应参数有相同含义，该函数执行成功，返回非0值，否则返回0。<br />
　　一般情况下，调用AfxBeginThread()来一次性地创建并启动一个线程，但是也可以通过两步法来创建线程：首先创建CWinThread类的一个对象，然后调用该对象的成员函数CreateThread()来启动该线程。</p>
<p>virtual BOOL CWinThread::InitInstance();<br />
　　重载该函数以控制用户界面线程实例的初始化。初始化成功则返回非0值，否则返回0。用户界面线程经常重载该函数，工作者线程一般不使用InitInstance()。</p>
<p>virtual int CWinThread::ExitInstance();<br />
　　在线程终结前重载该函数进行一些必要的清理工作。该函数返回线程的退出码，0表示执行成功，非0值用来标识各种错误。同InitInstance()成员函数一样，该函数也只适用于用户界面线程。</p>
<p>二、线程通信与、同步与互斥</p>
<p>全局变量实现通信<br />
事件（Event）是Windows为线程同步而提供的一种内核对象（进程和线程也是内核对象）。一个事件可用进程中惟一的32位句柄来标识。它也可以用名字来标识，它的句柄可以被复制，以便在进程之间共享。一个事件可以是有信号状态（signaled）或者无信号状态（non-signaled）；事件有两种类型——手工重置和自动重置。MFC提供一个方便的类CEvent，它从CSyncObject派生。默认情况下，它的构造函数会创建一个Win32自动重置型的事件对象，并处于无信号状态。如果将事件对象声明为全局对象，则任何线程都可以很容易的访问它们，而线程间可以用CEvent::SetEvent来设置适当的事件为有信号状态而实现通信。对有信号状态的事件要进行响应，可以通过MFC提供的CSingleLock类，但使用Win32的WaitForSingleObject或WaitForMultipleObjects函数更容易。<br />
一般情况下，要避免使线程阻塞，可以在主程序里调用TerminateThread函数来终止线程，但这可能会存在内存泄漏的情况。<br />
MFC提供了CCriticalSection类，它封装了Windows临界区句柄。它的构造函数调用Win32的InitializeCriticalSection函数，Lock与Unlock成员函数分别调用EnterCriticalSection和LeaveCriticalSection，析构函数调用DeleteCriticalSection。<br />
CEvent和CCriticalSection只能在同一进程中的不同线程中实现同步，要想实现不同进程间的数据访问控制，就需要互斥体或信号。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/07/05/windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

