Chapter04-进程

1 进程产生

定义:

一般定义为正在运行程序的一个实例,由以下两部分组成:

  1. 一个内核对象,操作系统用它管理进程。
  2. 一个地址空间,其中包含所有可执行文件或DLL。

系统创建一个进程时,会自动为进程创建第一个线程,称为主线程。

 

应用程序类型

入口点函数

嵌入可执行文件的启动函数

ANSI的GUI应用程序

_tWinMain

WinMainCRTStartup

Unicode….GUI….

_tWinMain

wWinMainCRTStartup

ANSI….CUI….

_tmain

mainCRTStartup

Unicode….CUI….

_tmain

wmainCRTStartup

 

CUI和GUI程序的区别在于编译器链接不同入口点函数,在项目属性的子系统里设置:
/SUBSYSTEM:CONSOLE
/SUBSYSTEM:WINDOWS
如果删除该选项,则由程序自动确定。

 

获取环境变量:
GUI:调用GetEnvironmentStrings函数
CUI:通过传递进来的main函数所接受的TCHAR* env[]参数来实现

判断环境变量是否存在:
调用GetEnvironmentVariable函数。
获取环境变量的值:
WCHAR *pszVarName = TEXT("%USERPROFILE%");
WCHAR pszVarValue[MAX_PATH];
ExpandEnvironmentStrings(pszVarName,pszVarValue,MAX_PATH);
这时pszVarValue的值就变成了pszVarName所代表环境变量的具体路径。

添加或删除环境变量:
调用SetEnvironmentVariable函数,第一个参数为函数名,第二个参数为函数路径,如果第二个参数为NULL,则删除。

线程可以调用GetCurrentDirectory和SetCurrentDirectory来获取和设置其所在的当前驱动器和目录:
WCHAR str[MAX_PATH];
GetCurrentDirectory(MAX_PATH,str);

获取当前系统版本:
调用GetVersion/GetVersionEx函数,使用OSVERSIONINFOEX结构。
Vista提供了VerifyVersionInfo函数,用来比较主机系统的版本和应用程序的版本。

创建新进程:
调用CreateProcess函数。如果系统成功创建了新进程和其主线程,返回TRUE。
该函数的第二个参数pszCommandLine用来表示命令行的参数,也可传进完整的程序路径,执行程序。
传进去的该是个“非常量字符串”
编译器有个/ZI开关,允许“调试时编辑并继续”/GF用来消除重复的常量字符串。
即使第一个参数给了要执行的参数,CreateProcess仍会将pszCommandLine参数中的内容作为新进程的命令行传递给它。
psaProcess、psaThread、bInheritHandles参数是用来指定新进程的安全性的,如果给NULL,则使用默认的安全属性。
psiStartInfo参数用来传递一些启动参数,比如窗口大小、坐标等,一般用默认值,但要注意,在使用前要将该结构清空。
STARTUPINFO si = { sizeof(si) };

还有几个属性,用到时再说吧,下面给段简单的CreateProcess使用代码:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szCommandLine[] = TEXT(“NOTEPAD”);
CreateProcess(NULL,szCommandLine,NULL,NULL,
                         FALSE,0,NULL,NUL,&si,&pi);

方法

优缺点

其他

主线程返回

进程中的对象都会被正确析构和销毁

操作系统将正确释放线程栈使用的内存

系统将进程的退出代码设为入口函数返回值

系统递减进程内核对象使用计数

一切都会被正确清理

进程中一个线程调用ExitProcess函数

调用ExitProcess和ExitThread会导致进程或线程直接终止运行。C/C++运行库也许不能执行正确清理工作。因为它造成进程当场死亡,可能没来得及执行清理工作。
详见P101给出代码

应该避免

另一个进程调用TerminateProcess函数

任何线程都可以调用TerminateProcess来终止自己或其他进程。它是异步的,为了确保进程已经终止,应调用WaitForSingleObject来进行确认。

应该避免,一旦进程终止,操作系统保证不会泄露任何东西

自然死亡

小概率事件……基本不会发生

系统终止时进行的操作:P103


子进程:
生成一个新的进程来帮我们完成工作,新的进程称为子进程。
在使用子进程时,需要调用WaitForSingleObject来确认是否执行完成。


进程终止

  • 基线程(primary thread)的入口函数自动返回.例如通常的main函数返回。
    • 在基线程的入口函数退出时必须确保:
      • 所有的该线程创建的C++对象都调用了对应的析构函数。
      • 操作系统已经释放了所有申请的线程堆栈。
      • 系统在入口函数的返回值中甚至了退出代码值(exit code)
      • 系统将减少进程内核对象(process kernel object)的引用值(usage count)

  • 在进程的一个线程中调用ExitProcess函数。

  •         如果进程正常地从基线程(primary thread)的入口函数退出,则会自动清理和释放

  资源。但是如果直接调用ExitProcess函数则就是直接地粗暴地退出进程。

    1. #include <windows.h>  
    2. #include <stdio.h>  
    3. class CSomeObj   
    4. {  
    5.     public:  
    6.         CSomeObj() { printf("Constructor\r\n"); }  
    7.         ~CSomeObj() { printf("Destructor\r\n"); }  
    8. };  
    9.   
    10. CSomeObj g_GlobalObj;  
    11.   
    12. void main ()   
    13. {  
    14.     CSomeObj LocalObj;  
    15.     ExitProcess(0);   
    16.       
    17.     // This shouldn't be here  
    18.     // At the end of this function, the compiler automatically added  
    19.     // the code necessary to call LocalObj's destructor.  
    20.     // ExitProcess prevents it from executing.  
    21. }  
    22. /* 
    23. 调用ExitProcess的输出结果: 
    24.     Constructor 
    25.     Constructor 
    26.      
    27. 不调用ExitProcess的输出结果: 
    28.     Constructor 
    29.     Constructor 
    30.     Destructor 
    31.     Destructor 
    32. */  


  • 在其他进程的线程中调用TerminateProcess函数。
BOOL TerminateProcess(HANDLE hProcess,UINT fuExitCode);
TerminateProcess函数和ExitProcess函数的一个主要的不同点就是:TerminateProcess
函数可以通过进程对应hProcess的句柄参数来终止任意进程,而ExitProcess函数只能终止
调用该函数的进程。
TerminateProcess函数函数是异步的,调用该函数只是通知系统该进程要退出,但并不能
保证进程就能马上退出。

  • 该进程中的所有线程都死掉了。


一个进程退出时,将会执行以下操作:
  • 进程中的所有线程都将终止。
  • 所有的用户对象和GDI都会被释放。都有的内核对象(Kernel Objects)都会被释放。
  • 函数的 exit code 从 STILL_ACTIVE 变成ExitProcess或TerminateProcess函数的返回值
  • 进程内核对象(process kernel object)的状态变成已触发状态。
  • 进程内核对象(process kernel object)的引用值减一。

PS:
当一个进程退出,就不存在“资源泄漏”的说法。因为进程退出时系统会清理所有的数据。
但是当一个资源不需要就应该用代码将其释放。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值