菏泽网站建设 梧桐树,html5软件官网,网页预览手机网站效果,推广平台都有哪些进程
进程要做任何事情#xff0c;必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候#xff0c;会自动为进程创建第一个线程#xff0c;这称为主线程#xff08;…进程
进程要做任何事情必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候会自动为进程创建第一个线程这称为主线程primary thread。
对于所有要运行的线程操作系统会轮流为每个线程调度一些CPU时间。会采取round-robin的方式。
两部分
一个内核对象
一个地址空间 Windows程序
Windows支持两种类型的应用程序GUI程序和CUI程序。前者是图形用户界面后者是控制台用户界面。这两种应用程序的界限是模糊的。
用Microsoft Visual Studio来创建一个应用程序项目的时候继承开发环境会设置各种链接器开关。
对于CUI程序这个链接器开关是/SUBSYSTEM:CONSOLE
对于GUI程序这个链接器开关是/SUBSYSTEM:WINDOWS
操作系统的加载程序会检查可执行文件映像的文件头并获取这个子系统值。如果此值表明是一个CUI程序加载程序会自动确保有一个可用的文本台窗口如果此值表明是一个GUI程序加载器就不会创建控制台窗口。
Windows程序必须有一个入口点函数应用程序开始运行时这个函数会被调用。
C/C采用下面两种入口点函数
Int WINAPI_tWinMain(HINSTANCE hInstanceExe,HINSTANCE,PTSTR pszCmdLine,int nCmdShow);int _tmain(int argc,TCHAR *argv[],TCHAR *envp[]);
具体的符号取决于是否使用Unicode字符串操作系统并不调用入口点函数。相反它会调用C/C运行库并在链接时使用-entry:命令行选项来设置的一个C/C运行时启动函数。该函数将初始化C/C运行库使我们能调用malloc和free之类的函数。还确保了在我们的代码开始执行之前我们声明的任何全局和静态C对象都被正确的构造。
应用程序类型入口点函数入口嵌入可执行文件的启动函数处理ANSI字符和字符串的GUI应用程序_tWinMain(Winmain)WinMainCRTStartup处理Unicode字符和字符串的GUI应用程序 _tWinMain(w Winmain) wWinMainCRTStartup处理ANSI字符和字符串的CUI应用程序_tmain(Main)mainCRTStartup处理Unicode字符和字符串的CUI应用程序 _tmain(Wmain) wmainCRTStartup
所有C/C运行库启动函数所做的事情基本都是一样的区别在于它们要处理的是ANSI字符串还是Unicode字符串在初始化C运行库之后它们调用的是哪一个入口点函数。Visual C自带C运行库的源代码。可以在crtree.c文件中找到4个启动函数的源代码。
用途如下
获取指向新进程的完整命令行的一个指针获取指向新进程的环境变量的一个指针初始化C/C运行库的全局变量。如果包含了StdLib.h我们的代码就可以访问一些变量初始化C运行库内存分配函数和其他I/O例程使用的堆调用所有全局和静态C类对象的构造函数
完成这些初始化工作之后C/C程序就会调用应用程序的入口点函数。
调用过程如下
GetStartupInfo(StartupInfo);
int nMainRetValWinMain((HINSTANCE)_ImageBase,NULL,pszCommandLineUnicode,(StartupInfo.dwFlagsSTARTF_USESHOWWINDOW)?StartupInfo.wShowWindow:SW_SHOWDEFAULT);
_Image是操作系统定义的一个伪变量表明可执行文件被映射到应用程序内存中的什么位置。 进程实例句柄
加载到进程地址空间的每一个可执行文件或者DLL文件都被赋予了一个独一无二的实例句柄。可执行文件的实例句柄。可执行文件的实例被当作(w)WinMain函数的第一个参数hInstanceExe传入。在需要加载资源的函数调用中一般都要提供此句柄的值。例如为了从可执行文件的映像中加载一个图标资源就需要调用下面这个函数
HICON LoadIcon(HINSTANCE hInstance,PCTSTR pszIcon);
LoadIcon函数的第一个参数指出哪个文件包含了想要加载的资源。许多应用程序都会将(w)WinMain的hInstanceExe参数保存在一个全局变量中使其很容易被可执行文件的所有代码访问。
hInstanceExe参数的实际值是一个内存基地址系统将可执行文件的映像加载到进程地址空间中的这个位置。例如假如系统打开可执行文件并将它的内容加载到0x00400000则w(WinMain)的hInstanceExe参数值为0x04000000。
可执行文件的映像具体加载到哪一个基地址是由链接器决定的。不同的链接器使用不同的默认基地址。Visual Studio链接器使用的默认基地址是0x00400000这是在运行Windows 98时可执行文件的映像能加载到的最低的一个地址。使用Microsoft链接器/BASE:address链接器开关可以更改要将应用程序加载到哪个基地址。
为了知道一个可执行文件或DLL文件被加载到进程地址空间的什么位置可以使用GetModuleHandle函数来返回一个句柄/基地址
HMUDULE GetModuleHandle(PCTSTR pszModule);
调用这个函数时要传递一个以0为终止符的字符串它指定了已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。如果系统找到了指定的可执行文件或DLL文件名称GetModuleHandle就会返回可执行文件DLL文件映像加载到的基地址。 进程的命令行
系统在创建一个新进程时会传一个命令行给它。这个命令行几乎总是非空的
用于创建新进程的可执行文件的名称是命令行上的第一个标记token
C运行库的启动代码开始执行一个GUI应用程序时会调用Windows函数GetCommandLine来获取进程的完整命令行忽略可执行文件的名称然后将指向命令行剩余部分的一个指针传给WinMain的pszCmdLine函数
应用程序可以通过自己选择的任何一种方式来分析和解释命令行字符串。 进程的环境变量
每个进程都有一个与它关联的环境块这是在进程地址空间内分配的一块内存其中包含字符串和下面类似
可以使用GetEnvironmentStrings函数来获取完整的环境块。
用户登录Windows时系统会创建shell进程并将一组环境字符串与其关联。
系统通过检查注册表中的两个注册表项来获得初始的环境字符串。
第一个注册表包含应用于系统的所有环境变量的列表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
第二个注册表项包含应用于当前登录用户的所有环境变量的列表
HKEY_CURRENT_USER\Environment
用户可以添加删除或更该这些环境变量具体做法是从Control Panel中选择System然后单击Advanced System Settings然后点击Environment Variable按钮。 要有管理员权限才能更改system variable列表中包含的变量
应用程序还可以使用各种注册表函数来修改这些注册表项
但是为了使改动对所有应用程序生效用户必须注销并重新登录有的应用程序在其主窗口接收到WM_SETTINGCHANGE消息时用新的注册表来更新它们的环境块。
通常子进程会继承一组环境变量这些环境变量和父进程的环境变量相同。不过父进程可以控制哪些环境变量允许子进程继承。子进程和父进程并不共享一个环境块。
可以用GetEnvironmentVariable函数来判断一个环节变量是否存在
DWORD GetEnvironmentVariable(PCTSTR pszName,PTSTR pszValue,DWORD cchValue);
pszName用于指定预期的变量名称pszValue指向保存变量的缓冲区cchValue指出缓冲区大小
找到就返回复制到缓冲区的字符数没有找到就返回0
ExpandEnvironmentStrings函数
DWORD ExpandEnvironmentStrings(PCTSTR pszSrc,PTSTR pszDSt,DWORD chSize);
pszSrc参数是包含“可替换环境变量字符串”的一个字符串地址。pszDst参数是用于接收扩展字符串的一个缓冲区地址。chSize参数是这个缓冲区的最大大小。
用SetEnvironmentVariable函数添加一个变量删除一个变量或者修改一个变量的值
BOOL SetEnvironmentVariable(PCTSTR pszName,PCTSTR pszValue);
将pszName所标识的一个变量设为pszValue参数所标识的值如果已经有了这个名称的变量就会修改值如果pszValue设置为NULL就会删除该变量 进程的关联性
进程中的线程都在主机的任何CPU上执行也可以强迫线程在可用CPU的一个子集上运行。这就是进程的管理性。
进程的错误模式
每个进程都关联了一组标志这些标志的作用是让系统知道进程如何响应严重错误。
包括磁盘介质错误未处理的异常文件查找错误以及数据对齐错误
进程可以调用SetErrorMode函数来告诉系统如何处理这些错误
UINT SetErrorMode(UINT fuErrorMode);
fuErrorMode参数
标志描述SEM_FAILCRITICALERRORS系统不显示严重错误处理程序消息框并将错误返回主调进程SEM_NOGPFAULTERRORBOX系统不显示常规保护错误消息框此标志只应该由调试程序设置该调试程序用一个异常处理程序来自行处理常规保护SEM_NOOPENFILEERRORBOX系统查找文件失败不显示消息框SEM_NOALIGNMENTFAULTEXCEPT系统自动修复内存对齐错误并使应用程序看不到这些错误
默认情况下子进程会继承父进程的错误模式标志
进程当前所在的驱动器和目录
使用CreateFile来打开一个文件系统将在当前驱动器和目录查找该文件
一个线程可以调用以下两个函数来获取和设置其所在进程的当前驱动器和目录
DWORD GetCurrentDirectory(DWORD cchCurDir,PTSTR pszCurDir);BOOL SetCurrentDirectory(PCTSTR pszCurDir);