Qt-Windows系统进程间通信实践 – CPU相关性

前言

本文是《Qt-Windows系统进程间通信实践 - 进程优先级》的扩展部分,程序修改部分为在原有程序的基础上,为各个udp客户端的返回数据中加入本进程的PID,并在主控端对指定的PID进行操作,文章略有重复,仅作折腾记录。运行界面如下

实现功能(黄色为新增

  1. 主控端可选择能够进行相互连接的子程序
  2. 子程序可由主控端进行踢出或者设置CPU运行优先级
  3. 可选择是否在所有子程序退出后主控端一同退出
  4. 可选择是否在任何一个子程序退出后所有其他子程序与主控端全部退出
  5. 所有子程序均可根据运行时传入端口号参数决定是否加入udp监听
  6. 子程序端口号根据主控端监听端口自动加1
  7. 可对选取的目标进程进行CPU核心相关性(亲和性)设置,可单个可组合。

运行流程

1. 程序启动后,可手动添加支持udp连接的客户端子程序
2. 添加成功后客户端会发送一条启动的udp消息,服务端收到并展示。
3. 服务端对客户端的“移除”与变更进程优先级操作均通过udp包发送给客户端,udp包中包含有目标程序所包含的端口号(简单起见以此来区分哪个客户端应该对此包做出回应)与当前进程的PID。
4. 客户端主动退出后会给服务端发送指定格式udp包,服务端收到后根据配置决定单独退出此程序或者全部退出。
5. 控制端(服务端)对指定的PID进行CPU相关性操作将直接进行系统调用(System Call)

UDP数据包格式分隔符为###

示例1:SERVERMSG###TERMINATE###[MSGCONTENT]
SERVERMSG: 服务端发往客户端的信息
TERMINATE: 表示执行关闭程序操作
MSGCONTENT: 表示此次操作需携带的数据(可空)

示例2:SERVERMSG###PRIORITY###2
SERVERMSG: 服务端发往客户端的信息
PRIORITY: 表示设置客户端进程的优先级
2: 设置优先级为2(HIGH_PRIORITY_CLASS:High,高优先级类)

示例3:CLIENTMSG###CopyCoinFlip:9001 started###PID
CLIENTMSG: 客户端发往服务端的信息
CopyCoinFlip:9001 started: 通知型信息,消息主体为监听9001端口的程序CopyCoinFlip启动了
PID: 当前进程的PID

程序逻辑验证方法

  1. 在服务端对指定进程右键设置CPU相关性之后,可根据进程PID在windows的资源管理器中进行查看,在CommandDashBoard中设置的CPU相关性会在windows资源管理中得到体现,反之在windows资源管理器中进行了CPU亲和性设置之后在CommandDashboard中也会得到展示,两边的状态显示与操作都是互通的,如图

可以看到两边同为7576的PID显示的CPU相关性相同,对其中任何一个进行设置之后都会同步在对方的状态显示中。

  1. 无限循环测试。

新增一个名为CommandDashboard-TestClient1的程序,其内容为两个按钮触发无限循环。第一个按钮直接无线循环并更新UI,显然界面会假死;第二个按钮为在独立线程中执行上述操作,界面会过一段时间假死,过一段时间恢复,下图

上述两个按钮的目的在于,使用CommandDashboard控制端对其进行CPU亲和度设置时观察CPU核心的负载状态,得到结论如下:

  1. CPU核心绑定进程时,无限循环中观察到每个核心的负载初期差别不大,1-2分钟后负载明显,如图

  2. CPU核心绑定到线程时,无限循环中可以明显观察到负载均衡的差别,如下图

可以明显观察到CPU3的负载比其他核心高。

关于本程序的局限性

  1. 系统调用平台关联性强,目前只支持windows平台
  2. 只在单处理器多核心场景验证过(Intel I3 4核心),不支持多处理器多核心

与本文相关的项目及源程序

  1. CommandDashboard 负责添加配套的udp客户端,可对其进行运行优先级调整,关闭等操作
  2. CommandDashboard-TestClient1 udp客户端程序,模拟进程循环和线程循环用于观察CPU核心的负载变化
  3. MyDockButtonDemo、CopyCoinFlip 均为CommandDashboard的udp客户端

项目下载地址

https://pan.baidu.com/s/1MJ08H7TBHRgd8AsaVDxtAg?pwd=8xjn

参考资料

  1. windows 系统资源获取的c++ 方法_bruce_wang_janet的博客-CSDN博客
  2. C++ (Cpp) GetProcessAffinityMask示例 - HotExamples
  3. SetThreadAffinityMask function (winbase.h) - Win32 apps | Microsoft Docs
  4. windows下绑定线程(进程)到指定的CPU核心 - Avatarx - 博客园 (cnblogs.com)
  5. 用SetProcessAffinityMask为进程指定CPU_zdleek的博客-CSDN博客
  6. windows下设置线程亲和性(支持大于64核)_百里杨的博客-CSDN博客_线程亲和性