windows下C++多线程学习之一(多线程基础)

作为一个C++程序员,相信大家对多线程都不陌生。最近自己在系统的学习多线程编程,发现了很多曾经没有注意到的东西,系统的整理了一下这些知识。方便自己以后查阅,也希望能够能够方便他人。


一、线程基础

 

1.      作业—> 进程—> 线程

作业:进程组的概念,将进程添加到一个作业中,能够通过作业内核对象来集中控制,设置一些额外的属性。

进程:一个正在运行的程序实例,由系统用来管理进程的内核对象和地址空间组成。进程时不活泼的,它只是线程的容器,每个进程必须有一个线程。

线程:程序执行流的最小单元,必须在某个进程环境中创建,由线程内核对象和线程堆栈组成。


2.      进程被初始化时,系统就会创建一个主线程,主线程的进入点函数必须为:main、wmain、WinMain、wWinMain。


3.      线程创建函数:CreateThread()、_beginthreadex();(建议后者,前者有可能造成内存泄露)

CreateThread():  系统API

_beginthreadex(): CRT(c运行期可函数)(参数与上面一样)

 

HANDLE CreateThread(

LPSECURITY_ATTRIBUTESlpThreadAttributes,//安全属性 NULL默认

SIZE_T dwStackSize,//initialstacksize  出事栈大小,0默认

LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction线程函数地址

LPVOID lpParameter,//threadargument  传递给线程函数的参数

DWORDdwCreationFlags,//creationoption  线程标志,挂起或者激活(0)

LPDWORDlpThreadId//threadidentifier   返回线程ID

)

 

 

_beginthreadex()内部会调用CreateThread()函数,但是在调用CreateThread函数之前,它会为线程申请一个_tiddata结构,用于存储线程相关数据;如线程ID,线程handle,errno值等等。线程结束_beginthreadex()内部会自动调用_endthreadex(), _endthread()会释放掉_tiddata结构分配的内存,并且会调用CloseHandle()来关闭线程句柄。

 

调用CreateThread()函数来创建的线程,不会为线程分配_tiddata结构。但是当我们调用某些C运行期库函数时,如:strtok(),就会需要_tiddata这个结构,就会发现线程没有申请_tiddata结构,这时它会申请这个结构并且初始化。可是这个自动申请的结构谁来释放呢?

当一个进程/线程开始或者退出时,每个DLL的DllMain都会被调用,在DllMain中会释放掉线程的_tiddata。可是静态链接库没有DllMain,这样就没办法释放掉_tiddata,这是可能造成内存泄露的一种情况。


4.      线程终止:

线程函数返回     (最好使用此方式)

ExitThread()                (某些资源不能撤销,如:C++类对象)

TerminateThread()   (异步运行函数,不能保证线程被撤销)

进程终止

 

二、线程间通信

1. 全局数据结构。与同属一个进程的其它线程共享进程所拥有的全部资源。

2. 参数

 

3.PostThreadMessage(),线程之间异步通讯,将消息放入指定线程的消息队列里,不等待线程处理消息就返回。

PostThreadMessage()有时会失败,报1444错误。可能是线程不存在,也有可能是线程不存在消息队列。调用PeekMessage或GetMessage会强制系统为该线程创建消息队列。


你可能感兴趣的:(windows,C++)