📄 sy0602.htm
字号:
<html>
<HEAD>
<TITLE>Visual C++与计算机接口</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=gb2312" >
</HEAD>
<body>
<font color="#0000FF">多线程的使用</font>
<p>
(一)实验目的:<BR>
学习多线程的使用<BR><BR>
(二)线程<BR><BR>
在Win32中,每个运行的程序就是一个进程,而每个进程可以由一个或多个线程组成。<BR>
进程的所有线程共享进程的代码、资源、内存和全局变量。<BR>
进程是从单一线程开始启动的,其他线程是根据需要被动态创建的。<BR>
一个线程其实就是一条独立的执行程序代码的路径。如果一个进程创建了多个线程,就有多条路径执行代码,而且代码在相应路径上是并行执行的(分时处理)。<BR><BR>
在Win32中,线程为拥有CPU时间的最小实体,CPU会为所有进程的每个活动线程分配一份处理时间,甚至可以依据线程的优先级分配不均等的时间片。<BR>
由于CPU把时间片分得很小——大约20毫秒左右,因此,多线程会令人认为似乎当前的所有活动线程都在同时工作。<BR><BR>
1、使用线程的益处:<BR>
·多线程使得进程能够同时执行多个任务。例如应用程序可以使用一个线程来处理鼠标键盘等的用户输入,而使用其他较低优先级的线程来进行计算或后台打印等。<BR>
·多线程在MDI应用程序中也很有用处。当打开多个窗口时,不同的线程可以分别指派给各个窗口,用于处理个窗口的事务。<BR>
·多线程在网络和通信方面有很大用处。例如一个网络服务程序可以为连接来的每个客户创建一个线程。线程亦可帮助应用程序处理来自多个通信设备的输入。<BR><BR>
2、何时使用线程:<BR>
·有效的分摊任务。<BR>
·对不同的任务赋予不同的优先级。<BR>
·后台处理。<BR>
·分摊并行任务的执行。<BR><BR>
3、创建线程:<BR>
在MFC中,创建线程通常使用AfxBeginThread()函数:<BR>
CWinThread* AfxBeginThread(lpThreadFunc, pParam);<BR>
或 CWinThread* AfxBeginThread(lpThreadFunc, pParam, nPriority);<BR>
其中lpThreadFunc:线程函数。<BR>
pParam:传递给线程函数的实参,可以是任意32位数据。<BR>
nPriority:线程优先级。缺省为THREAD_PRIORITY_NORMAL。<BR><BR>
线程函数是线程的执行路径,该函数的执行和退出也就是线程的启动和终止,函数的执行过程也就是线程的执行过程。<BR>
线程函数原型为:UINT ThreadFunc(LPVOID pParam);<BR>
线程函数必须为一个全局函数,其唯一参数由AfxBeginThread()传递传递,传递的实参根据线程的需要而定。<BR><BR>
AfxBeginThread()的返回值是一个CWinThread对象的指针。取得该返回值并不十分必要,但若需要访问该线程,例如获取线程信息、终止线程、设置优先级等,就应该接受这一返回值。<BR><BR>
(三)实验步骤:<BR><BR>
1、建立一个MFC应用程序。<BR><BR>
2、下载<a href="anim.h">anim.h</a>和<a href="anim.cpp">anim.cpp</a>,并加入到新建的Project中。<BR>
这两个文件用于管理图形和动画,主要工作是先利用MemDC将图形准备好,再在需要的时候BitBlt到DC中。<BR><BR>
3、在View类的头文件中添加:<BR>
#include "anim.h"<BR>
UINT ThreadFunc(LPVOID pParam);<BR><BR>
4、在View类中添加成员变量和成员函数:<BR>
class MAnimation *m_pAnimation;<BR>
void Animate();<BR><BR>
5、在View类中加入WM_CREATE消息映射函数OnCreate(),并加入代码:<BR>
m_pAnimation = new MAnimation(m_hWnd);<BR>
AfxBeginThread(ThreadFunc,this);<BR><BR>
6、在View类的cpp文件中手工加入函数Animate():<BR>
void CTttView::Animate()<BR>
{<BR>
RECT rcClient;<BR>
GetClientRect(&rcClient);<BR>
m_pAnimation->AnimateShape(rcClient);<BR>
}<BR><BR>
7、在View类中加入WM_SIZE消息映射函数OnSize(),并加入代码:<BR>
m_pAnimation->SetSize(m_hWnd, nType, cx, cy);<BR>
Invalidate();<BR><BR>
8、在View类的cpp文件中加入线程函数:<BR>
UINT ThreadFunc(LPVOID pParam)<BR>
{<BR>
while (TRUE)<BR>
{<BR>
((CTttView *)pParam)->Animate();<BR>
Sleep(10);<BR>
}<BR>
return true;<BR>
}<BR><BR>
9、编译运行,查看结果。<BR><BR>
以上步骤即为:<BR>
·在View类中定义一个MAnimation指针<BR>
·在OnCreate函数中创建MAnimation对象,并开启线程<BR>
·在OnSize函数中调用MAnimation的函数改变图形的大小<BR>
·还可以定义函数并调用MAnimation的函数改变图形的颜色、速度等<BR>
·线程不停的调用MAnimation的函数绘制图形<BR>
·线程中使用Sleep以控制绘制图形的速度<BR><BR>
运行此程序,可以看到当关闭主窗口时没有问题,但若只关闭一个子窗口,将会出现错误。<BR>
这是因为线程不是依附于窗口的,子窗口虽然关闭了,但线程却不会主动关闭。<BR>
线程可以强制关闭,只需调用AfxEndThread()函数。但这可能会引起内存泄露等多种问题。<BR>
一般情况下,线程总应该由自身直接终止。其他线程可以通过一个同步信号或共享变量,通知被终止的线程。被终止的线程接到通知后,即可正常退出。<BR><BR>
<a href="l0602.exe">执行文件示例</a>
<p></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -