Windows进程机制

进程

进程要做任何事情,必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候,会自动为进程创建第一个线程,这称为主线程(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个启动函数的源代码。

用途如下:

  1. 获取指向新进程的完整命令行的一个指针
  2. 获取指向新进程的环境变量的一个指针
  3. 初始化C/C++运行库的全局变量。如果包含了StdLib.h,我们的代码就可以访问一些变量
  4. 初始化C运行库内存分配函数和其他I/O例程使用的堆
  5. 调用所有全局和静态C++类对象的构造函数

完成这些初始化工作之后,C/C++程序就会调用应用程序的入口点函数。

调用过程如下

GetStartupInfo(&StartupInfo);
int nMainRetVal=&WinMain((HINSTANCE)&_ImageBase,NULL,pszCommandLineUnicode,(StartupInfo.dwFlags&STARTF_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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247472.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

word文档怎么压缩?超级好用!

当Word文档体积过大时,会遇到传输慢、无法上传等问题,这时候可以通过压缩软件、压缩图片等方式减小Word文档体积,下面就一起来看下具体的操作方法吧。 方法一:嗨格式压缩大师 嗨格式压缩大师是一个专业的压缩软件,可以…

分享10个国内免费的AI绘画工具

谈到 AI 绘画,许多人会联想到 Midjourney、Stable Diffusion、DALLE2 等国外的知名绘画工具。 然而,这些国外的 AI 绘画工具大部分都是付费的,并且需要借助科学上网才能使用。这两个条件让许多人望而却步。 考虑到很多人无法进行科学上网&a…

绿色视角下的高校校园建设及能耗管理

摘 要:2019年住建部发布了《绿色校园评价标准》(GB/T51356—2019),将创建绿色校园提上了日程。绿色校园建设的目标是践行绿色发展理念,建立生态文明教育工作长效机制。创建绿色校园要从政府、社会、学校三个层面来实施,以加快高校…

【Spring Boot】Starter机制的使用及案例

一、引言 1、什么是SpringBoot Starter SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启…

【MIMO 从入门到精通】[P3]【Channel Estimation】

前言: MIMO 是无线通讯里面的核心技术之一.这里面主要参考 《Quick Introduction to MIMO Channel Estimation》 Professor and an IEEE Fellow:Iain 讲解一下 MIMO (multiple transmit antennas and multiple receivers)里面的信…

电脑出现错误0x80004005怎么解决,解决0x80004005的问题

当电脑出现0x80004005错误时,通常是由于系统或应用程序之间的通信问题或文件系统损坏引起的。该错误代码表示未指定错误,在Windows系统中较为常见。 一.解决0x80004005错误的步骤 重新启动电脑 有时候,错误只是一个暂时的问题,重…

后端项目操作数据库-中枢组件Service调用Mapper实现增删改查-实例

接上篇 使用MyBatis配置Mapper实现增删改查 1.Service的基本作用 Service在代码中的的作用是调用Mapper、被Controller调用。是后端项目中非常重要的组件。 用于设计业务流程、业务逻辑,以保障数据的完整性、有效性、安全性。 2. Service使用举例——“添加相册”…

MyBatis的逆向工程

MyBatis的逆向工程 正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工 程的 逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源: Java实体类 Mapp…

【Trino权威指南(第二版)】Trino的架构、trino架构组件、 trino连接器架构的细节、trino的查询执行模型

文章目录 一. Trino架构1. 架构概览2. 协调器3. 发现服务4. 工作节点 二. 基于连接器的架构三. 查询执行模型1. 解析—>查询计划2. 查询计划 —> 分布式查询计划3. 运行阶段3.1. 基础概念切片:并行单元page 与 exchange算子pipeline切片的driverOperator 3.2.…

Python高级算法——线性规划(Linear Programming)

Python中的线性规划(Linear Programming):高级算法解析 线性规划是一种数学优化方法,用于求解线性目标函数在线性约束条件下的最优解。它在运筹学、经济学、工程等领域得到广泛应用。本文将深入讲解Python中的线性规划&#xff0…

连续型随机变量的概率密度

如果对于随机变量的分布函数,存在非负可积函数,使得对于任意实数,有: 那么就称为连续型随机变量,称为的概率密度函数,简称密度函数。

微信小程序合集更更更之实现雪花随机飘落

实现效果 写在最后🍒 更多相关内容,关注🍥苏苏的bug,🍡苏苏的github,🍪苏苏的码云~

为MES实施建立成功的团队:应对挑战并确保成功

前言 实施MES是一个复杂且具有挑战性的过程,需要协调良好的团队共同努力。 为了取得成功,建立一支具有专业技能、专业知识和共同愿景的团队组合成为致胜的关键。本文将探讨组建MES团队的关键要素,例如: 确定关键利益相关者和决策…

产品经理之Axure的元件库使用详细案例

⭐⭐ 产品经理专栏:产品专栏 ⭐⭐ 个人主页:个人主页 ​ 目录 前言 一.Axure的元件库的使用 1.1 元件介绍 1.2 基本元件的使用 1.2.1 矩形、按钮、标题的使用 1.2.2 图片及热区的使用 1.3 表单元件及表格元件的使用 1.3.1表单元件的使用 1.3.…

VSCode解决本地浏览器需要跨域问题

这里写目录标题 测试用代码执行代码后控制台报错现象解决方案 测试用代码 先把测试用的代码贴出来 测试代码结构 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…

基于CNN+数据增强+残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)+数据集+模型(四)

系列文章目录 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xff08;一&#xff09; 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xf…

飞天使-docker知识点8-docker的资源限制

文章目录 容器资源限制示例 容器资源限制 Docker提供了多种资源限制的方式&#xff0c;可以根据应用程序的需求和系统资源的可用性进行选择。以下是一些常见的Docker资源限制及其使用情况&#xff1a;CPU限制&#xff1a;通过设置CPU的配额&#xff08;quota&#xff09;和周期…

YOLOv8-Seg改进:UniRepLKNetBlock 助力分割 | UniRepLKNet,通用感知大内核卷积网络, 2023.12

🚀🚀🚀本文改进: UniRepLKNet,通用感知大内核卷积网络,ImageNet-22K预训练,精度 和速度SOTA,ImageNet达到88%, COCO达到56.4 box AP,ADE20K达到55.6 mIoU UniRepLKNetBlock 与C2f进行结合使用 🚀🚀🚀YOLOv8-seg创新专栏:http://t.csdnimg.cn/KLSdv 学姐带…

安装NLTK Data

文章目录 NLTK离线安装1. 获取安装包2. 放置nltk_data文件3. Demo4. 参考链接 关注公众号&#xff1a;『AI学习星球』 算法学习、4对1辅导、论文辅导或核心期刊可以通过公众号或CSDN滴滴我 nltk库是python语言为自然语言处理提供的一个功能强大&#xff0c;简单易用的函数库&a…

AUTOSAR组织引入了Rust语言的原因是什么?有哪些好处?与C++相比它有什么优点?并推荐一些入门学习Rust语言链接等

AUTOSAR(汽车开放系统架构)是一个由汽车制造商、供应商和其他来自电子、半导体和软件行业的公司组成的全球发展伙伴关系,自2003年以来一直致力于为汽车行业开发和引入开放、标准化的软件平台。 AUTOSAR 最近宣布成立一个新的工作组,用于探索在汽车软件中使用 Rust 编程语言…