windows多线程编程一 windows多线程编程c
一、什么是进程和线程
进程和线程的区别:
进程主要包括:(1)私有虚拟地址空间(2)可执行程序(代码和数据)(3)打开系统资源列表句柄(4)进程ID(5)安全访问标志(6)至少一个执行线程
线程主要包括:(1)一组Cpu寄存器状态(2)两个堆栈(系统态和用户态)(3)线程局部存储区域TLS(4)线程ID(5)安全特性
进程是不活泼的,不执行任何东西,它是线程的容器
进程、模块和线程的关系:
模块是一段可执行程序代码、其代码、资源等被载入系统中,由系统创建一个结构体(MDB)来管理它。进程中包括虚拟地址空间、一系列模块组和线程组成,线程主要是执行模块中的可执行 代码。
二、Windows多线程编程之创建线程
注意事项:
(1)如果有共享变量,则一定要声明为volatile类型,比如多线程并发的控制变量
(2)声明生成线程后的线程句柄HANDLEhThread和所创建线程的生成的线程id DWORD ThreadId
(3)编写线程函数 ThreadFunc(…)
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
NULL,
0,
&ThreadID);
函数原型为HANDLE CreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:
"lpThreadAttributes:指向一个 SECURITY_ATTRIBUTES结构的指针,该结构决定了线程的安全属性,一般置为 NULL;
"dwStackSize:指定了线程的堆栈深度,一般都设置为0;
"lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc是线程函数名;
"lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;
"dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用;
"lpThreadId:该参数返回所创建线程的ID;
"如果创建成功则返回线程的句柄,否则返回NULL。
几个常用的Windows多线程函数:
DWORD SuspendThread(HANDLE thread),该函数用于挂起指定的线程
DWORD ResumeThread(HANDLE thread)用于结束线程的挂起状态
VOID ExitThread(DWORDdwExitCode);在线程执行函数中被调用,用于线程终结自身,参数dwExitCode用于设置函数的退出码
Void TerminateThread(HANDLE hThread,DWORDdwExitCode),强制退出,设置函数的退出码
BOOL PostThreadMessage(DWORD threaded,UINT Msg,WPARAMwParam,LPARAM lParam)
该函数将一条消息放入指定的线程消息队列中,立即返回。如果该线程没有创建消息循环,则该函数执行失败。
DWORD WaitForSingleObject(HANDLE hHandle,DWORDdwMilliseconds);
三、MFC下创建线程
MFC中分为两类线程,一类是用户界面线程,另一类是工作者线程,两类的区别就是有无消息循环机制。
MFC中一般用CWindThread*AfxBegineThread()来创建并初始化一个线程的运行,该函数有两种重载形式,分别用于创建工作者线程和界面线程
(1)CWinThread*AfxBeginThread(AFX_THREADPROCpfnThreadProc, LPVOID pParam, nPriority,UINT nStackSize, DWORDdwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
pfnThreadProc执行工作者线程的执行函数指针,线程函数必须声明如下:UINTExecutingFunction(LPVOID pParam);
"pParam:传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略;
"nPriority:线程的优先级。如果为0,则线程与其父线程具有相同的优先级;
"nStackSize:线程为自己分配堆栈的大小,其单位为字节。如果nStackSize被设为0,则线程的堆栈被设置成与父线程堆栈相同大小;
"dwCreateFlags:如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;
"lpSecurityAttrs:线程的安全属性指针,一般为NULL;
(2)界面线程:在界面线程中AfxBegineThread参数中线程函数和参数不同,其他都一样
CWinThread* AfxBeginThread(CRuntimeClass*pThreadClass,
int nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
在界面线程中,重载Inistance()和Existence()来初始化和界面和当界面退出时进行保存的工作
四、多线程之间的通讯
i.使用全局变量,用volatile进行修饰
ii.使用自定义消息进行通讯
注意事项:
(1)自定消息要在WM_USER值之上定义
(2)线程之间传递消息要用PostThreadMessage();
(3)在消息影射表中进行影射:如果是主线程用ON_MESSAGE(),普通线程用ON_THREAD_MESSAGE(WM_MESSAGE,fun);
(4)定义消息处理函数:如果是普通线程处理函数,前面要加上afx_msgLONG fun(UINT wParam, LONG lParam)
(5)实现的时候,前面一定要加上类名,否则会出现连接错误LONGCLASSNAME::fun();
(6)线程一定要有自己的消息对列才可以接收消息,vc中从CWinThread中继承的,都有消息队列
更多阅读
长跑前吃什么 长跑之前吃什么好
长跑前吃什么——简介最近参加了一些长跑比赛,从个人经验和一些资料来看,长跑前的饮食非常重要。长跑前吃什么——方法/步骤长跑前吃什么 1、赛前一周长跑运动时间长、消耗大,赛前一周的也饮食也特别重要。主要是增加一些提升耐力的
数据库安装程序配置服务器失败。 u8数据库服务器失败
安装程序配置服务器失败。参考服务器错误日志和 C:WINDOWSsqlstp.log 了解更多信息。在C:Program FilesMicrosoft?SQL?Server文件夹下的(80和MSSQL文件夹)全部删除解决方法一:解决方法是把计算机名改成大写就行了,具体操作,右键我的电
常见美白成分大排名 美白成分
辣么多的美白产品、辣么多的美白成分,是不是有点傻傻看不清?到底哪个有效、哪个刺激、哪个安全、哪个无良?冰寒总结了常见(还不是所有)的美白成分的原理、特点,附上中英文名,希望对你的美白大计有帮助:)一、最经典:维生素C及衍生物维生素C(
linux中socket编程中使用send发送结构体小结 c socket 结构体
客套话不说了:socket中的send函数可以发送字符串,不能直接发送结构体,自己理解:结构体即内存中一段连续的内存,这样send中可以发送结构体指针 上代码:代码功能:客户端发送给服务端一个结构体,服务端返回客户端一字符串客户端代码 client.
喉咙干痒咳嗽怎么办 精 喉咙痒老咳嗽怎么办
冬季又到了使用空调的高峰时节,空调房间环境封闭,空气流动性较差,使室内温度、湿度适合病菌的繁衍、生存。在这样的环境中,很容易感染微生物引发咽喉炎、扁桃体炎等疾病。因此,空调房间不宜久留,冬季也应多到室外走走、活动一下身体;多吃