Windows原理与应用(二)——程序进程与进程间通信
系列
Windows原理与应用(一)—— 简介 | 德依安-BLOG (ddg-302.github.io)
[本文]Windows原理与应用(二)——程序进程与进程间通信 | 德依安-BLOG (ddg-302.github.io)
程序、进程与线程
进程与程序不同,它是程序执行时的标志,程序是存放在磁盘中的可执行文件,而进程是程序执行的一个过程,程序是静态的,进程是动态的
一个程序可执行多次产生多个进程实例,进程随运行动态变化,进程共享计算机资源、互相通信,由OS管理
线程是最小的执行单位,它几乎不拥有系统资源,它是系统调度的基本单位
在单CPU单核技术中,OS不断切换线程运行,这个过程成为并发;多核或多CPU中的程序可以并行
一个进程可以拥有多个线程,一个线程只属于一个进程
操作系统中的进程
- 操作系统中的进程与用户进程并发运行,用户进程由操作系统创建和调用
- 用户进程也可以创建和调用别的进程
- 被创建的进程与创建者构成父子关系
进程与线程的关系图
进程对象结构
Windows将硬件资源虚拟后分配给进程,还创建多种软件资源
软件资源分为两类,一类是只能由操作系统管理和使用的
内核资源
,如权限令牌,底层时间,互斥量等;另一类是用户程序使用的资源,如普通内存空间,文件资源等内核资源
:每个内核对象是由系统内和创建的一块内存区,这块内存区的数据结构成员对应对象的属性,在初次创建内核对象时,创建函数获得标识这个内核的句柄
(HANDLE
),句柄只能由特定的API调用,不可以直接操作句柄
:句柄是一个4B(64位机中为8B)长的数值,用于标识应用程序中的不同实例,要注意句柄不是指针,它只是表示一个对象,这个对象的物理地址由操作系统安排,物理地址并不是固定的,但句柄值是固定的,需要使用指定的API才可以操作句柄指向的对象句柄是进程相关的,同一个句柄值在不同进程中意义不同
关闭使用完毕的资源句柄后,系统不会马上销毁它,内核对象生命期可以比创建它的进程长
进程创建过程
- 打开文件映像
- 创建Windows进程对象
- 创建初始线程对象,为其分配内存堆栈、运行上下文
- 通知内核系统为进程运行作准备
- 执行初始线程
- 导入需要的DLL,初始化地址空间,由程序入口地址开始执行进程
进程的创建与启动 - C#
创建wpf工程
实例化一个Process类并打开应用程序,Process类在System.Diagnostics命名空间下
1 | using System.Diagnostics; |
- 关闭应用程序
1 | // 法1 |
1 | // 法2 |
进程间通信
- 高级通信(IPC[1])
- 传输数据量大,超过几十个字节
- 低级通信(同步控制)
- 传输数据量小,少于数个字节,或仅是位单位
进程间通信方法分类
- 共享内存(剪贴板、COM、DLL、DDE、文件映射)
- 消息WM_COPYDATA
- 邮槽
- 管道(有名管道,无名管道)
- Windows套接字
- NetBIOS特殊的网络应用
IPC选择考虑
- 通信主题是进程内的线程还是不同进程之间
- 进程是需要网络还是本地机制
- 通信的进程运行的OS是否有差异
- 有些进程通信机制是只用于图形化窗体界面的,而不适用于控制台程序
- 通信目的是用于同步控制还是大量数据的交换
管道通信
由操作系统创建管道对象,发送进程向管道中写数据,接收进程从管道中读数据
无名管道
- 只能在单一进程内使用
有名管道
- 以「文件名」来表示,可以用于不同进程间通信
管道通信实现
- 建立连接:服务端创建命名管道NamedPipeServerStream类实例,调用WaitForConnection方法等待连接,这个函数将阻塞线程
- 通信实现:建立连接后,客户端和服务端可以通过Stream流的Read方法和Write方法进行读写通信
- 连接终止:任何一方使用Close方法可以关闭管道连接
服务端:
1 | NamedPipeServerStream pipeserver; // 实例化 |
客户端:
1 | NamedPipeClientStream pclient = new NamedPipeClientStream(".", "my_pipe", PipeDirection.InOut); // 客户端连接名为「my_pipe」的管道 |
重定向方式
控制台进程文件描述符
- 标准输入
- 标准输出
- 标准错误输出
普通进程
- 从键盘接收输入→输出到屏幕
重定向
- 从文件输入→屏幕输出
- ……
例子
- 使用控制台重定向符
>
和<
- 使用控制台重定向符
1 | dir > file.txt // 将dir指令的输出存放到file.txt中 |
使用控制台重定向获取控制台输出实例
1 | using System.Diagnostics; |
练习
- 通过重定向机制实现进程间通信
- 调用getmac获取网卡mac
- 调用shutdown命令关闭或重启电脑
- 通过管道机制实现进程间通信
- 客户端向服务端发送数据
- 服务端显示数据
程序将会以WPF窗体程序的形式呈现,为了让输出显示在窗体上,将不使用Console.WriteLine()方法,而是会有一些特殊的处理,这也将在之后整理放出
- 1.IPC:interproces communications,是通信进程处于同一台机器中的通信机制,IPC经常使用C/S模式 ↩