多线程的创建与关闭-基于MFC对话框基础篇①

多抽出一分钟学习,让你的生命更加精彩

线程和进程的关系:(本人自己理解) 线程是进程的可执行单元,是计算机分配CPU时的基本单元。一个进程可以包含一个或多个线程,进程是通过线程去执行代码的,同一个进程的多个线程共享该进程的资源和操作系统分配给该进程的内存空间。每个进程必须有一个主线程,主线程退出后该进程也就退出。

在主线程main运行时创建了子线程,之后两个线程将会同时向前运行,如果主线程执行完毕了,就代表整个进程执行完毕了,如果其他子进程还没有执行完毕,则会被操作系统强行终止。

VC中创建线程的三种方式:
Ⅰ:CreatThread函数 Windows提供的标准的Win32函数,来进行线程的创建工作
Ⅱ:AfxBeginThread 应用于MFC中(有afx都和mfc有关)
Ⅲ:_beginthreadex 应用于C++中(用的不多)
方式Ⅱ和方式Ⅲ都是间接的调用方式Ⅰ,归根揭底都是方式一,但方式二和方式三有他们使用的地方。

先看方式Ⅰ:

Create Thread()函数
//参数Ⅰ:安全描述符指针,一般默认的传递NULL就好了,表示当前句柄不能被子进程所继承;
//参数Ⅱ:创建线程运行堆栈的大小,默认是1M(置零即可);
//参数Ⅲ(重要,和第四个参数配合使用):线程函数的地址;创建线程的目的是为了执行相应的功能,把这个功能函数的地方放到这里,系统会自动的调用;
//参数Ⅳ:传递给线程函数的参数(是指针类型);
//参数Ⅴ:创建线程的标志,创建完线程之后,不想马上执行,而是暂停一会再执行,默认执行则写0;
//参数Ⅵ:返回创建线程的ID(唯一的),不需要的话传递NULL。
该函数的返回值为HANDLE类型,如果执行成功,则返回当前新创建线程的句柄(句柄是一个整数,起标识作用)。
之后创建MFC对话框文件,添加一个按钮并在其点击事件中写如下测试程序:

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
 int tipMsg = (int)lpParameter;//将指针类型强转为int
 CString strMsg;
 strMsg.Format(_T("%d"), tipMsg);//将int类型转换为CString类型(MFC字符串)
 AfxMessageBox(strMsg); //弹出一个对话框 
 return 0;
}

void C多线程Dlg::OnBnClickedBtn()
{
 // TODO: 在此添加控件通知处理程序代码
 DWORD dwThreadID = 0;
 HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)123, 0,&dwThreadID);//线程函数的参数要是指针类型,我们强转一下即可
 CloseHandle(hThread);//主线程不需要此线程时,要释放资源,不释放会导致内存泄漏。
}

执行该程序,点击按钮即可创建线程,其依据是弹出对话框。

方式Ⅱ(MFC情况下用,但MFC情况下也可以用方式Ⅰ):

MFC中封装了一个线程的类CWinThread,通过这个类来进行线程的一些操作。AfxBeginThread 函数的返回值就是一个CWinThread对象。AfxBeginThread 函数不像CreatThread函数那样需要设置六个参数,且可以创建两种线程:工作线程和界面线程。先说工作线程:上个例子就是工作线程它进行的是一些计算工作,和界面没有太多关系的操作,不建议在工作线程中直接操纵界面上面的控件,有可能会出现异常。
AfxBeginThread 函数:
参数Ⅰ:是线程函数的地址;
参数Ⅱ:线程函数的参数;
参数Ⅲ:线程函数的优先级,自带默认参数;
参数Ⅳ:默认新线程的堆栈大小;
参数Ⅴ:创建的标志(默认或挂起);
参数Ⅵ:安全描述指针 (后四个参数都有默认值,完全不用传递,只需要前两个参数)
该函数返回值为CWinThread的指针,包含了创建的新线程的信息,如线程的句柄,线程的ID等。==如果用刚才方式Ⅰ定义的线程函数,则编译不通过,==因为定义方式不对,该创建线程的函数对应的线程函数要用如下方式定义:

UINT _cdecl ThreadProc(LPVOID lpParameter)
{
 int tipMsg = (int)lpParameter;//将指针类型强转为int
 CString strMsg;
 strMsg.Format(_T("%d"), tipMsg);//将int类型转换为CString类型(MFC字符串)
 AfxMessageBox(strMsg); //弹出一个对话框 
 return 0;
}

void C多线程Dlg::OnBnClickedBtn()
{
//  TODO: 在此添加控件通知处理程序代码
CWinThread *pThread = AfxBeginThread(ThreadProc,(LPVOID)456);
}

通过该方式生成的*pThread里的线程句柄不需要进行手动释放,会自动的进行释放。

The end。

猜你喜欢

转载自blog.csdn.net/qq_42308217/article/details/108411585
今日推荐