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);

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

命令调用先构建hashTable

GPT 代码改 #include <stdio.h> #include <stdlib.h> #include <string.h>#define TABLE_SIZE 256struct Node {char *key;void *value;struct Node *next; };struct HashTable {struct Node *table[TABLE_SIZE]; };void initHashTable(struct HashTable *ha…

GPT-AI导航

1. https://ai-bot.cn/ https://ai-bot.cn/

工业固体废物智能化综合管控平台

工业固体废物智能化综合管控平台&#xff0c;涵盖产废企业、运输企业、固废处置企 业等不同群体应用&#xff0c;根据不同群体设计不同的业务应用子系统功能&#xff0c;以及各个不 同群体的环保物联网平台子系统功能模块&#xff0c;同时具有移动端的应用APP。 建立产废企业端…

C++ stringOJ练习题

目录 把字符串转换成整数 反转字符串 字符串中的第一个唯一字符 字符串最后一个单词的长度 找出字符串中第一个只出现一次的字符 字符串相加 字符串最后一个单词长度 字符串相乘 反转字符串3 反转字符串2 验证回文串 把字符串转换成整数 通过遍历字符串并逐位转换…

phpy 连接 PHP与Python生态 跨界合作 PHPY搭建 已解决

目录 需求介绍 安装 windows版本 文件地址 运行效果 需求介绍 在日常功能开发中&#xff0c;难免会使用python的计算库&#xff0c;同时自己要是一名PHP开发工程师。就在最近有相应的需求&#xff0c;索性使用phpy来进行功能开发 安装 windows版本 phpy 是识沃团队最新推出…

千梦网创:Too Young,to simple

大多数人啊&#xff0c;还是too young&#xff0c;包括我。 网上的评论对我而言并不影响我通过提供价值服务经营生活&#xff0c;但是有时候对于我的思考还是有一些帮助的。 我把很多可以争与不可争的事件看做是一种现象&#xff0c;这种现象往往可以给予我新的能量。 当学员…

双端队列和优先级队列

文章目录 前言dequedeque底层设计迭代器设计 priority仿函数数组中的第k个最大元素优先级队列模拟实现pushpop调整仿函数存储自定义类型 前言 今天要介绍比较特殊的结构&#xff0c;双端队列。 还有一个适配器&#xff0c;优先级队列。 deque 栈的默认容器用了一个deque的东西…

【C语言(十三)】

自定义类型&#xff1a;结构体 一、结构体类型的声明 1.1、结构体回顾 结构是⼀些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.1.1、结构的声明 例如描述⼀个学生&#xff1a; struct Stu {char name[20];//名字int age;//年龄c…

三层交换,DHCP的详解与VRRP

目录 一、三层交换 1、三层交换机的作用&#xff1a; 2.vlan的虚拟接口vlanif&#xff08;ifinterface接口&#xff09; 3.三层交换机实验 4.拓展实验​编辑 二、DHCP 1.自动获取ip地址&#xff1a; 2.DHCP的好处&#xff1a; 3.分配方式&#xff1a; 4.举例&#xff…

分布式消息传递新时代:深入了解RabbitMQ_sharding插件的精髓【RabbitMQ 八】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 分布式消息传递新时代&#xff1a;深入了解RabbitMQ_sharding插件的精髓 引言前言基础概念以及原理配置和使用应用场景结语 引言 &#x1f33a;&#xff1a;docker构建rabbitmq并配置延迟队列插件 ⏳…

KAKFA实践零碎记录

这里写目录标题 1 内存泄露2 生产者报错 1 内存泄露 错误信息 反复执行&#xff1a;创建消费者->关闭消费者后&#xff0c;内存缓慢上升且GC不能回收内存 错误原因 关闭消费者需要执行KafkaConsumer#close()函数 public void close() {this.close(Duration.ofMillis(30000…

Linux——进程中被打开的文件

C语言中有着许多对文件操作的函数&#xff0c;包括其他语言也有&#xff0c;但是从语言来了解文件有点浅显计算机的一切都离不开操作系统&#xff0c;那么文件跟操作系统也有着密切的关系&#xff0c;所以我们从系统层面来了解文件&#xff08;在进程中打开的文件&#xff09;文…

数据结构之---- 排序算法

数据结构之---- 排序算法 什么是排序算法&#xff1f; 排序算法用于对一组数据按照特定顺序进行排列。 排序算法有着广泛的应用&#xff0c;因为有序数据通常能够被更有效地查找、分析和处理。 如图所示&#xff0c;排序算法中的数据类型可以是整数、浮点数、字符或字符串等…

NXP应用随记(四):eMios阅读随记-整体功能概述

目录 1、eMios IP介绍 2、时钟结构 3、通道类型 4、功能介绍 5、中断与DMA 6、EMIOS -通道分配建议(针对S32K312) 1、eMios IP介绍 Emios是什么&#xff1f;eMIOS提供了独立的通道(UCs)&#xff0c;您可以配置这些通道来为不同的功能生成或测量时间事件。 每个eMIOS实例最…

本地项目添加到gitlab命令操作

gitlab上面创建一个跟项目名同名的文件夹 创建文件夹&#xff0c;填写信息 添加readme文档&#xff0c;先保存下创建的文件夹 回到项目&#xff0c;复制项目的git 地址 然后进入到本地项目的文件夹&#xff0c;如d:/workspace/spring-demo&#xff0c;右键打开git bash弹框 命令…

【C语言】二分查找(详解)

&#x1f3a5; 岁月失语唯石能言的个人主页 &#x1f525;个人栏专&#xff1a;秒懂C语言 ⭐若在许我少年时&#xff0c;一两黄金一两风 一、二分查找的思路 二分查找是一种高效的查找算法&#xff0c;尤其适用于有序数组。它的基本思想是通过将查找区间逐步缩小…

Amortized Bootstrapping of LWE:使用 BFV 打包处理

参考文献&#xff1a; [AP13] Alperin-Sheriff J, Peikert C. Practical bootstrapping in quasilinear time[C]//Annual Cryptology Conference. Berlin, Heidelberg: Springer Berlin Heidelberg, 2013: 1-20.[MS18] Micciancio D, Sorrell J. Ring packing and amortized F…

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

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

【动手学深度学习】(十四)数据增广+微调

文章目录 一、数据增强1.理论知识2.代码 二、微调1.理论知识 一、数据增强 1.理论知识 增加一个已有数据集&#xff0c;使得有更多的多样性 在语言里面加入各种不同的背景噪音改变图片的颜色和形状 使用增强数据训练 翻转 左右翻转上下翻转 不总是可行 切割 从图片中切…