线程是系统内核对象之一。在学习线程之前,应先了解一下内核对象。内核对象是系统内核分配的一个内存块,该内存块描述的是一个数据结构,其成员负责维护对象的各种信息。内核对象的数据只能由系统内核来访问,应用程序无法在内存中找到这些数据结构并直接改变他们的内容。
常用的系统内核对象有事件对象、文件对象、作业对象、互斥对象、管道对象、进程对象和线程对象等。不同类型的内核对象,其数据结构各有不同。
进程被认为是一个正在运行的程序的实例,它也属于系统内核对象。可以将进程简单的理解为一个容器,它只是提供空间,执行程序的代码是由线程来实现的。线程存在于进程中,它负责执行进程地址空间中的代码。当一个进程创建时,系统会自动为其创建一个线程,该线程被称为主线程。在主线程中用户可以通过代码创建其他线程,当进程中的主线程结束时,进程也就结束了。
Windows下,创建线程有多种方式,以下将逐一介绍。注意它们的区别。
Windows API函数。该函数在主线程的基础上创建一个新线程。微软在Windows API中提供了建立新的线程的函数CreateThread。
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程安全属性
DWORD dwStackSize,//堆栈大小
LPTHREAD_START_ROUTINE lpStartAddress,//线程函数
LPVOID lpParameter,//线程参数
DWORD dwCreationFlags,//线程创建属性
LPDWORD lpThreadId//线程ID
);
代码示例如下:
#include "stdafx.h"
#include
#include
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
cout << "thread function Fun1Proc!\n";
return 0;
}
int main()
{
HANDLE hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
CloseHandle(hThread1);
Sleep(1000);
cout << "main end!\n";
system("pause");
return 0;
}
除了使用CreateThread API函数创建线程外,还可以用C++语言提供的_beginthreadex函数来创建线程。
uintptr_t _beginthreadex( // NATIVE CODE
void *security, //线程安全属性
unsigned stack_size, //线程的栈大小
unsigned ( *start_address )( void * ),//线程函数
void *arglist, //传递到线程函数中的参数
unsigned initflag, //线程初始化标记
unsigned *thrdaddr //线程ID
);
代码示例:
#include "stdafx.h"
#include
#include
#include
using namespace std;
unsigned int _stdcall ThreadProc(LPVOID lpParameter)
{
cout << "thread function ThreadProc!\n";
return 0;
}
int main()
{
_beginthreadex(NULL, 0, ThreadProc, 0, 0, NULL);
Sleep(1000);
cout << "main end!\n";
system("pause");
return 0;
}
在MFC应用程序中,还可以使用AfxBeginThread函数创建一个线程。MFC提供了两个重载版的AfxBeginThread,一个用于用户界面线程,另一个用于工作者线程。这里只讲工作者线程。
CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID lParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);//用于创建工作者线程
返回值: 成功时返回一个指向新线程的线程对象的指针,否则NULL。
pfnThreadProc : 线程的入口函数,声明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能设置为NULL;
pParam : 传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程.
nPriority : 线程的优先级,一般设置为 0 .让它和主线程具有共同的优先级.
nStackSize : 指定新创建的线程的栈的大小.如果为 0,新创建的线程具有和主线程一样的大小的栈
dwCreateFlags : 指定创建线程以后,线程有怎么样的标志.可以指定两个值:
lpSecurityAttrs : 指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性。如果为 NULL,那么新创建的线程就具有和主线程一样的安全性。
代码略。
创建线程还可以用boost线程库创建,也可以用c++11新标准中的线程库(std::thread)创建线程。建议采用c++11中的线程库创建线程,极为方便。且跨平台,是语言层面的。后面会学习到c++11线程库的使用。
最后,搜索并关注微信公众号:让我思考一下。获得最新技术分享!