文章目录
创建线程
1. CreateTread
函数的具体格式如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadID
);
参数说明:
lpThreadAttrivutes
:指向SECURITY_ATTRIBUTES
的指针,用于定义新线程的安全属性,一般设置成NULL
;dwStackSize
:分配以字节数表示的线程堆栈的大小,默认值是0
;lpStartAddress
:指向一个线程函数地址。每个线程都有自己的线程函数,线程函数是线程具体的执行代码;lpParameter
:传递给线程函数的参数;dwCreationFlags
:表示创建线程的运行状态,其中CREATE_SUSPEND
表示挂起当前创建的线程,而0表示立即执行当前创建的进程;lpThreadID
:返回新创建的线程的ID编号;
返回值:
成功返回新线程的句柄,失败返回NULL
1.线程函数的声明
必须是全局函数或者是静态成员函数。这里使用全局变量
DWORD WINAPI ThreadProc(LPVOID lpParam);//声明全局函数主要是线程处理函数
2.声明传入参数
为了传入多个参数,这里我们一般是采用结构体的。
//为了传递多个参数,采用结构体
struct threadInfo
{
HWND hWnd; //窗口句柄
int nOffset;//偏移量
COLORREF clrRGB; //颜色
};
3.类中声明需要传递参数
protected:
HANDLE hThread[4];//用来存储线程句柄
DWORD dwThreadID[4];//用于存放线程的ID
threadInfo Info[3];//用于传递线程所需要的参数
4.创建线程
for (int i = 0; i < 3; i++)
{
hThread[i] = CreateThread(NULL, 0, ThreadProc, &Info[i], 0, &dwThreadID[i]);
//注意不需要使用,需要释放线程句柄
CloseHandle(hThread[i]);
}
DWORD __stdcall ThreadProc(LPVOID lpParam)//全局函数方式下的线程函数
{
threadInfo*Info = (threadInfo*)lpParam;
CString str;
str.Format(_T("%d"), Info->nOffset);//输出一下便宜量
AfxMessageBox(str);
return 0;
}
2. 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* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
参数说明:
pfnThreadProc
:指向工作线程的控制函数。不能是NULL。这个函数必须按下面的方式定义:
UINT MyControllingFunction( LPVOID pParam );
pThreadClass
:从CWinThread继承的对象的RUNTIME_CLASS。pParam
: 将要传送给控制函数的参数,如pfnThreadProc中定义的函数参数所示。nPriority
: 设定的线程的优先级。如果为0,则使用与创建它线程相同的优先级。nStackSize
: 指定新线程使用的栈的以字节为单位的大小。如果为0,则缺省的栈大小与创建它的线程的栈大小相同。dwCreateFlags
: 指定控制线程的创建过程的附加标志。这个标志可以是两个值之一: ①CREATE_SUSPENDED
经过一个延迟后启动这个线程。这个线程将在调用ResumeThread 以后才会启动。 ② 0 创建后立即启动这个线程。lpSecurityAttrs
指向一个SECURITY_ATTRIBUTES结构,它指定了线程的安全特性。如果为空,将使用与创建它的线程相同的安全特性。如果需要获得有关这个结构的详细信息,
返回值:
指向新创建的线程对象的指针。
AfxBeginThread创建一个新的CWinThread对象,调用它的CreateThread函数以启动这个线程,并且返回这个线程的指针。整个过程都进行检查以保证如果创建失败,所有的对象都会被适当地释放。为了结束这个线程,可以在线程内调用AfxEndThread,或者从工作线程的控制函数内返回。
1.线程函数的声明
必须是全局函数或者是静态成员函数。一般使用静态成员函数作为线程传入整个类对象
//方式一:定义全局函数
UINT MyThreadFunction(LPVOID pParam);
//方式二:类中的静态成员
protected:
static UINT MyThread(LPVOID pParam);
public:
int m_number;
2. 创建线程
//线程函数调用主对话框类的成员:线程函数的参数起着决定性作用!
CWinThread *pThread = AfxBeginThread(MyThread, this);//使用this,可以调用类中的成员
m_number = 0;//初始值
//CWinThread *pThread = AfxBeginThread(MyThreadFunction, &Info[i]);
//线程函数的方法
UINT CThreadDlg::MyThread(LPVOID pParam)
{
CThreadTestDlg* pdlg = (CThreadTestDlg*)pParam;
int iMsg = pdlg->m_number;
CString str;
while (TRUE)
{
str.Format(_T("%d"), iMsg++);
OutputDebugString(str);
Sleep(50);
//在线程中调用AfxEndThread来关闭线程
if (iMsg == 50)
{
AfxEndThread(0);//关闭线程
}
}
return 0;
}
3. _beginthreadex
待补充
总结
1、CreateThread
,线程中不使用CRT,不使用MFC库
2、_beginthreadex
,线程中使用CRT,不使用MFC库,初始化CRT后,调用CreateThread
3、AfxbeginThread
,线程中使用CRT,使用MFC库,或者其中任何之一,初始化MFC后,调用_beginthreadex
MFC中线程创建的函数,首先创建了相应的CWinThread对象,然后调用CWinThread::CreateThread,在CWinThread::CreateThread中完成了对线程对象的初始化工作,然后,调用_beginthreadex创建线程。注意不要在一个MFC程序中使用_beginthreadex()或CreateThread()。