线程(一)-线程的创建

一.理解系统内核对象


线程是系统内核对象之一.内核对象是系统内核分配的一个内存块,该内存块描述的是一个数据结构,其成员负责维护对象的各种信息.内核对象只能由系统内核来访问,应用程序无法在内存中找到这些数据结构并直接改变他们的内容。

常用的系统内核对象有事件对象、文件对象、作业对象、互斥对象、管道对象、进程对象和线程对象。

内核对象共性:
1.计数属性,内核对象在进程中被创建,但不被进程所拥有,当创建一个内核对象时,内核对象的使用计数为1,当其他进程访问该内核对象时,使用计数将递增1.当内核对象的使用计数为0,系统内核将撤销该对象。
2.安全属性,由安全描述符来表示。


二.使用CreateThread函数创建线程


HANDLE CreateThead(
LPSECURITY_ATTRIBUTES lpsa;
DWORD cdStack;
LPTHREAD_START_ROUTINE lpStartAddr;
LPVOID lpvThreadParam;
DWORD fdwCreate;
LPDWORD lplDThread);
DWORD __stdcall ThreadProc(LPVOID lpParameter)
lpsa:线程安全属性信息,如果为NULL,表示线程句柄不被子进程继承
cbStack:线程的栈大小,可以为0
lpStartAddr:线程函数,线程运行时将执行该函数
lpvThreadParam:传递到线程函数中的参数
fdwCreate:线程创建的标记
lpIDThread:一个整型指针,用于接收线程ID。如果参数为NULL,表示线程ID不被返回。
{
 CMultiThreadDlg* pDlg = (CMultiThreadDlg*)lpParameter;
 CString str;
 for (int i=0; i<99999;i++)
 {
  str.Format("%d",i);
  pDlg->m_Edit.SetWindowText(str);
  //pDlg->m_Edit.Invalidate();
 }
 return 0;
}

void CMultiThreadDlg::OnOK() 
{
 m_hThread = CreateThread(NULL,0,ThreadProc,this,0,NULL); 
}

三.C++语言提供的_beginthreadex


uintptr_t _beginthreadex(void *security,unsigned stack_size,unsigned(*start_address)(void *),void *arglist.unsigned initflag,unsigned *thrdaddr);
security:线程安全属性信息,如果为NULL,表示线程句柄不被子进程继承
stack_size:现成的栈大小,可以为0
start_address:线程函数,线程运行时将执行该函数
arglist:传递到线程函数中的参数
initflag:线程的初始化标记,为0,表示线程立即执行线程函数,为CREATE_SUSPENDED。表示线程暂时被挂起
thrdaddr:一个整型指针,用于返回线程ID
要使用_beginthreadex函数,需要在工程中引用process.h头文件
unsigned int __stdcall ThreadProc(LPVOID lpParameter)
{
 CMultyThreadDlg* pDlg = (CMultyThreadDlg*)lpParameter;
 pDlg->m_Prog.SetRange32(0,999999);
 for (int i=0; i<999999;i++)
 {
  pDlg->m_Prog.SetPos(i);
 }
 return 0;
}
void CMultyThreadDlg::OnOK() 
{
 m_hThread = (HANDLE)_beginthreadex(NULL,0,ThreadProc,this,0,NULL);
}



四.MFC应用程序中,可以使用AfxBeginThread函数


CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,LPVOID pParam,int nPriority=THREAD_PRIORITY_NORMAL,UINT nStackSize=0,DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
CWinThread* AfxBeginThread(CRuntimeClass* pTreadClass,int nPriority=THREAD_PRIORITY_NORMAL,UINT nStackSize=0,DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
nParam:线程函数的参数
nPriority:现成的优先级
nStackSize:线程堆栈大小
dwCreateFlags:线程的创建标记
lpSecurityAttrs:线程的安全属性
pThreadClass:派生于CWinThread类的运行时类对象
UINT ThreadFun( LPVOID pThreadParam )
{
 COperateThreadDlg* pDlg = (COperateThreadDlg*)pThreadParam;
 pDlg->m_Prog.SetRange32(0,999999);
 for (int i=0; i<999999;i++)
 {
  pDlg->m_Prog.SetPos(i);
 }
 return 0;
}
void COperateThreadDlg::OnOK() 
{
 m_pThread = AfxBeginThread(ThreadFun,this,0,0,0,NULL);
}


五.应用MFC类库创建线程


MFC类库提供的CWinThread类封装了对线程的支持。工作者线程和用户界面线程
1.m_bAutoDelete
该成员确定在线程终止时,线程对象是否自动被释放
2.m_hThread
该成员表示线程对象关联的线程句柄
3.m_nThreadID
该成员英语记录线程ID
4.m_pMainWID
该成员表示应用程序的主窗口
5.m_pActiveWnd
如果线程是OLE服务器的一部分,该成员表示容器应用程序住窗口
6.CreateThread
该方法用于创建一个线程
BOOL CreateThread(DWORD dwCreateFlags=0,UINT nStackSize=0,LPSECURITY_ATTRBUTES lpSecurityAttrs=NULL);
dwCreateFlags:线程的创建标识,如果为CREATE_SUSPENDED,线程在创建后立即挂起,直到调用ResumeThread方法才能开始执行线程函数,如果为0,线程创建后立即执行
nStackSize:线程堆栈的大小,如果为0,堆栈的大小将于主线程堆栈的大小相同
lpSecurityAttrs:线程的安全属性
7.GetMainWnd
该方法用于获取应用程序的主窗口指针,如果是OLE服务器应用程序,该方法返回的事m_pActiveWnd成员,否者返回m_pMainWnd成员
virtual CWnd* GetMain();
8.ResumeThread
该方法用于重新唤醒线程,它将线程的挂起计数减1,如果线程的挂起计数为0,将开始执行线程
DWORD ResumeThread();
9.SuspendThread
该方法用于挂起线程
DWORD SuspendThread();
返回值:如果函数执行成功,返回为线程之前的挂起计数,否者为0xFFFFFFFF

六.线程的挂起、唤醒和终止


1.SuspendThread
该函数用于挂起线程
DWORD SuspendThread(HANDLE hThread); 
2.ResumeThread
该函数用于减少线程挂起的次数,如果线程挂起的次数为0,将唤醒线程
DWORD ResumeThread(HANDLE hThread);
3.ExitThread
该函数用于结束当前的线程
VOID ExitThread(DWORD dwExitCode);
4.TerminateThread
该函数用于强制终止线程的执行
BOOL TerminateThread(HANDLE hTread,DWORD dwExitCode;
5.用于获取一个已中止线程的退出代码
BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode);
::OnCancel() 
{
 DWORD dwExit = 0;
 if (m_pThread!= NULL)
 {
  GetExitCodeThread(m_pThread,&dwExit);
  if (dwExit ==STILL_ACTIVE)
   TerminateThread(m_pThread,0);
  delete m_pThread;
 }
 CDialog::OnCancel();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值