进程包括:
1)私有的虚地址空间;
2)可执行程序(代码与数据);
3)打开系统资源列表句柄;
4)安全访问标志;
5)进程ID;
6)至少有一个执行线程;
线程包括:
1)一组CPU寄存器状态;
2)两个堆栈(系统态与用户态);
3)TLS(线程局部存储区);
4)线程ID;
5)安全特性;
因此进程是不活泼的,它从来不执行任何东西,是线程的容器;
线程的分类:1)用户界面线程;2)工作线程;
一般说来一个程序是由一个UI线程和多个work线程组合的,UI线程中进行消息处理(getmessage()),工作线程处理业务逻辑;
线程函数的声明:
DWORD WINAPI TreadFunc(LPVOID);
线程的创建:
HANDLE CreateThread(。。。);
这里需要注意一点线程ID与进程ID一样是可重复使用的,具有一定的不可信性,因此最好操作他们时使用内核对象句柄;
线程的终止:
1)线程函数返回;
2)调用了ExitThread函数;
3)另一个线程调用了TerminateThread()函数;
4)包含线程的进程终止运行;
线程返回后要做的一些事情:
始终将线程设计成这样的形式,即当想要线程终止运行时,它们就能够返回;如果线程能够返回,就可以确保下列事项的实现;
1)线程函数中创建的所有C++对象均将通过它们的析构函数正确撤销;
2)os将正确释放线程堆栈使用的内存;
3)os将线程的退出代码设置为线程函数的返回值;
4)os将递减线程内核对象的使用计数;
ExitThread和TerminateThread函数基本在设计良好的程序中都不使用,原因如下:
ExitThread不能让函数中的C++对象正确的撤销;在ms的VC中可以用VC++运行库中的_endthreadex替代;
TermianteThread
1)他是异步操作,并不能保证想终止的线程已经终止了;
2)线程终止时,DLL通常接受通知,但改函数强迫线程终止,DLL不接收通知,这也能阻止适当的清除;
3)另外在拥有被终止线程的进程结束前,该线程的堆栈不会被释放;
C/C++运行库的考虑
CreateThread与_beginthreadex函数的区别
前者是操作系统的函数,后者是C/C++运行库函数,如果要使用到C/C++运行库中的一些线程不安全函数需要用_beginthreadex函数替代CreateThread函数来创建线程;
进程和线程的句柄和伪句柄
句柄:CreateProcess和CreateThread函数返回值
伪句柄:GetCurrentProcess();GetCurrentThread();
注意将伪句柄传入CloseHandle(..)会忽略并返回false;
将伪句柄转换为实句柄:DuplicateHandle(...)该函数会递增特定对象的使用计数,因此完成后应该对该对象进行释放;