线程创建的方式

创建线程

1. CreateTread

官方说明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()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值