|
进程是应用程序的执行实例。每个进程是由私有的虚拟地址空间、代码、数据和其他各程系统资源组成。进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。每个进程至少有一个线程(主执行线程)
进程的创建(系统)→启动执行该进程的主执行线程
主执行线程以函数地址形式(main, winmain)存在,主执行线程终止了,进程也就随之终止。
用户可以在应用程序中创建其他线程,多个线程并发运行于同一个进程中。使用进程的地址空间,全局变量,系统资源。
消隐过程是属于消耗CPU非常严重的运算密集的过程,传统的单线程程序设计会导致程序出现界面定格、鼠标键盘事件不响应等死机假象。应用多线程设计可避免上述现象,把运算密集的消隐过程放到另一个线程中进行,这样,程序界面能照常处理用户命令。
一、 VC++支持两种线程:用户界面线程和工作者线程
用户界面线程线程基类CWinThread,用户界面线程通常用于处理用户输入并响应各种事件和消息。
(一) 创建用户界面线程
Class MyThread : public CWinThread
{
}
(二) 必须重载InitInstance 线程初始化函数,
(三) 启动用户界面线程
CWinThread AfxBeginThread (
CRunTimeClass *pThreadClass, // MyThread
int nPriority= THREAD_PRIORITY _MORMAL ,//优先级
UINT nStackSize=0,//堆栈大小
DWORD dwCreateFlags=0,//附加标志
Lpsecurity-ATTRIBUTES lpSecurityAttrs=Null //安全属性
)
优先级有:
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_MORMAL(缺省)与创建线程的线程优先级一样
THREAD_PRIORITY_ABOVE---NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_CRITICAL最高
THREAD_PRIORITY_IDLE 最低
线程堆栈大小:0表示与创建线程时的堆栈大小一样;
附加标记:0表示正常启动,CREATE_SUSPENDED则创建线程为挂起状态,必须调用RESUME THREAD;
安全属性:不用(如线程可否在其它线程中强制终止)
工作者线程工作者线程没有用户界面,不能响应Windows消息。用于后台任务,计算,调度等工作。它由一个函数组成。
(一)编写控制函数
UINT ContrlFunction(LPVOID pParam)
{
……
return 0;//线程终止码,用于指明线程结束的原因,一般0表示成功
// STILL_ACTIVE正在运行0x103**
}
(二)启动工作者线程
CWinThread *AfxBeginThread (
AFX_THREADPROC pfnThreadProc,// ContrlFunction
LPVOID pPapam,//传递给控制函数的参数
Int n priority. //…以下与前同
UINT nStacdsize=0,
DWORD dwcreateFlags=0
LPSECURITY_ATTRIBUTES(psecurity Attrs=Null
)
二、线程终止:
(一) 正常终止
用户界面线程:调用PostQuitMessage (int nExitCode)
工作者线程:运行到return(UINT nExitCode),或AfxEndThread(UINT,nExitCode)
(二) 异常终止
Bool TerminateThread(Handle hThread ,//线程句柄
DWORD,dwExitCode//线程退出码
)
hThread 可在CwinThread::m-hThread 得到
三、几个常用函数
BOOL GetExitCodeThread (handle hthread,
LPDWORD , LPExitCode);
CWinThread的几个成员函数
int GetThreadPriority()
BOOL SetThreadPriority (int nPriority);
DWORD ResumeThread ();//激活线程,返回以前被挂起的次数
DWORD SuspendThread ();//挂起线程,可以挂起多次。
思考:线程可否挂起自己?
线程可否激活自己?
四、与多线程编程密切相关的几个类
由于线程是并行运行于系统间的,当它们访问相同的共享变量时会出现安全性问题。MFC 提供以下几个对象可方便有效地解决多线程出现的问题。
(一)、CSyncObject 同步对象的纯虚基类(纯虚——不能实例化)
BOOL Lock (DWORD dwTimeout==INFINITE)
BOOL UnLock()=0;
BOOL UnLock(LONG lCount,LPLONG LPPrevcount=Null)
1) CSemaphore类信号灯对象,它允许一定数目的线程访问某个共享资源,
::CSemaphore (LONG 1Initialcount=1,//0-MaxCount之间
LONG lMaxCount=1,//可同时访问的最大数
LPCTSTR pstrName=Null,//为对象的名字,在系统中唯一
LPSECURITY_ATTRIBUTES lpsaAttributes=NULL
);
2) CMutex互斥量对象,任一时刻只允许一个线程访问该资源
::CMutex(Bool bInitiallyown=false,//是否被创建它的线程所占有
LPCTSTR pstrName =Null,
LPsctstr安全属性=Null
);
3) CEvent,事件对象,一个线程通知其他线程一个事件发生了。
::CEvent(Bool bInitially =false
Bool bManualReset=false.(手动、自动类型)
LPcTsTR LpszName =Null,
LPsTSTR LpszName=Null.)
BOOL SetEvent();//设为有信号状态;不能用于自动类型
BOOL ResetEvent();//设为无信号状态;不能用于自动类型
BOOL PulseEvent();//先为有信号状态,自动设为无信号状态
//自动—只释放一个等待线程。
//手动 – 释放所有等待线程
//**等待事件函数
DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object to wait for
DWORD dwMilliseconds // time-out interval in milliseconds);
(二)、同步访问对象
1) CSingleLock 类
CSingleLock (CSyneObject *pObject, BOOL bInitialLock=false);
BOOL Lock (DWORD dwTimeout =INFINITE
Bool unlock( );
Bool IsLock( ).
2) CmultiLock类
CMultilock (CSyncObject ** ppObjects,
DWORD dwCount,
BOOL bInitialLock=false)
DWORD LOCK(DWORD dwTimeout=Infinite)
BOOL bWaitForAll=TRUE,
DWORD dwWadeMast=0)//其它放弃等待的条件
BOOL Unlock()
BOOL Islocked (DWORD dwObject)下标。 |
|