You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 2012下获取并修改活动进程处理器组的技术问询

刚好之前做过类似的多处理器组相关的开发,给你梳理下具体的实现方案,不管是C++还是C#都能搞定:

一、获取进程所属的处理器组

不管是查询还是修改,第一步都得拿到合法的进程句柄,注意打开进程时要申请对应的权限。

C++实现方式

Windows提供了专门的处理器组API,用GetProcessGroupAffinity就能拿到进程关联的处理器组信息。步骤大概是:

  1. 用OpenProcess打开目标进程,需要PROCESS_QUERY_INFORMATION权限
  2. 调用GetProcessGroupAffinity,先传入0获取需要的缓冲区大小,再分配内存获取实际的组数据
  3. 处理完记得关闭进程句柄

示例代码:

#include <windows.h>
#include <vector>
#include <iostream>

bool GetProcessProcessorGroups(DWORD processId, std::vector<WORD>& outGroups) {
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
    if (hProcess == NULL) {
        std::cerr << "OpenProcess failed: " << GetLastError() << std::endl;
        return false;
    }

    DWORD groupCount = 0;
    // 先获取需要的组数量
    if (!GetProcessGroupAffinity(hProcess, &groupCount, NULL)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            std::cerr << "GetProcessGroupAffinity failed: " << GetLastError() << std::endl;
            CloseHandle(hProcess);
            return false;
        }
    }

    std::vector<GROUP_AFFINITY> groupAffinities(groupCount);
    if (!GetProcessGroupAffinity(hProcess, &groupCount, groupAffinities.data())) {
        std::cerr << "GetProcessGroupAffinity failed: " << GetLastError() << std::endl;
        CloseHandle(hProcess);
        return false;
    }

    outGroups.clear();
    for (const auto& ga : groupAffinities) {
        outGroups.push_back(ga.Group);
    }

    CloseHandle(hProcess);
    return true;
}

// 调用示例
int main() {
    DWORD targetPid = 1234; // 替换成你的目标进程ID
    std::vector<WORD> groups;
    if (GetProcessProcessorGroups(targetPid, groups)) {
        std::cout << "Process " << targetPid << " belongs to groups: ";
        for (WORD g : groups) {
            std::cout << g << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

C#实现方式

C#需要通过P/Invoke调用Windows API,先定义对应的结构体和函数声明:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

public static class ProcessorGroupHelper
{
    [StructLayout(LayoutKind.Sequential)]
    private struct GROUP_AFFINITY
    {
        public UIntPtr Mask;
        public ushort Group;
        private ushort Reserved1;
        private ushort Reserved2;
        private ushort Reserved3;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool GetProcessGroupAffinity(IntPtr hProcess, ref uint groupCount, [Out] GROUP_AFFINITY[] groupAffinities);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    private const uint PROCESS_QUERY_INFORMATION = 0x0400;

    public static List<ushort> GetProcessGroups(uint processId)
    {
        var groups = new List<ushort>();
        IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, processId);
        if (hProcess == IntPtr.Zero)
        {
            Console.WriteLine($"OpenProcess failed: {Marshal.GetLastWin32Error()}");
            return groups;
        }

        uint groupCount = 0;
        // 获取所需的组数量
        if (!GetProcessGroupAffinity(hProcess, ref groupCount, null))
        {
            int error = Marshal.GetLastWin32Error();
            if (error != 122) // ERROR_INSUFFICIENT_BUFFER
            {
                Console.WriteLine($"GetProcessGroupAffinity failed: {error}");
                CloseHandle(hProcess);
                return groups;
            }
        }

        var groupAffinities = new GROUP_AFFINITY[groupCount];
        if (GetProcessGroupAffinity(hProcess, ref groupCount, groupAffinities))
        {
            foreach (var ga in groupAffinities)
            {
                groups.Add(ga.Group);
            }
        }
        else
        {
            Console.WriteLine($"GetProcessGroupAffinity failed: {Marshal.GetLastWin32Error()}");
        }

        CloseHandle(hProcess);
        return groups;
    }

    // 调用示例
    public static void Main()
    {
        uint targetPid = 1234; // 替换成目标进程ID
        var groups = GetProcessGroups(targetPid);
        Console.WriteLine($"Process {targetPid} belongs to groups: {string.Join(", ", groups)}");
    }
}
二、更新指定进程的处理器组

修改进程的处理器组需要用到SetProcessGroupAffinity函数,注意打开进程时要申请PROCESS_SET_INFORMATION权限,而且不是所有进程都能修改(比如系统核心进程可能会因为权限不足失败)。

C++实现方式

示例代码:

#include <windows.h>
#include <iostream>

bool SetProcessProcessorGroup(DWORD processId, WORD targetGroup) {
    HANDLE hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, processId);
    if (hProcess == NULL) {
        std::cerr << "OpenProcess failed: " << GetLastError() << std::endl;
        return false;
    }

    GROUP_AFFINITY newGroupAffinity = {0};
    newGroupAffinity.Group = targetGroup;
    // 设置该组的所有CPU核心掩码,也可以指定特定核心
    newGroupAffinity.Mask = GetActiveProcessorMask(targetGroup);

    GROUP_AFFINITY oldGroupAffinity = {0};
    if (!SetProcessGroupAffinity(hProcess, &newGroupAffinity, &oldGroupAffinity)) {
        std::cerr << "SetProcessGroupAffinity failed: " << GetLastError() << std::endl;
        CloseHandle(hProcess);
        return false;
    }

    std::cout << "Successfully changed process " << processId << " to group " << targetGroup << std::endl;
    std::cout << "Previous group: " << oldGroupAffinity.Group << std::endl;

    CloseHandle(hProcess);
    return true;
}

// 调用示例
int main() {
    DWORD targetPid = 1234; // 目标进程ID
    WORD targetGroup = 1; // 目标处理器组编号(从0开始)
    SetProcessProcessorGroup(targetPid, targetGroup);
    return 0;
}

C#实现方式

同样通过P/Invoke实现,补充对应的函数声明:

using System;
using System.Runtime.InteropServices;

public static class ProcessorGroupHelper
{
    // 之前的GROUP_AFFINITY结构体和其他函数声明保持不变

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool SetProcessGroupAffinity(IntPtr hProcess, [In] GROUP_AFFINITY[] newGroupAffinity, [Out] GROUP_AFFINITY[] oldGroupAffinity);

    [DllImport("kernel32.dll")]
    private static extern UIntPtr GetActiveProcessorMask(ushort GroupNumber);

    private const uint PROCESS_SET_INFORMATION = 0x0200;

    public static bool SetProcessToGroup(uint processId, ushort targetGroup)
    {
        IntPtr hProcess = OpenProcess(PROCESS_SET_INFORMATION, false, processId);
        if (hProcess == IntPtr.Zero)
        {
            Console.WriteLine($"OpenProcess failed: {Marshal.GetLastWin32Error()}");
            return false;
        }

        var newGroupAffinity = new GROUP_AFFINITY[1];
        newGroupAffinity[0].Group = targetGroup;
        newGroupAffinity[0].Mask = GetActiveProcessorMask(targetGroup);

        var oldGroupAffinity = new GROUP_AFFINITY[1];
        bool success = SetProcessGroupAffinity(hProcess, newGroupAffinity, oldGroupAffinity);
        if (success)
        {
            Console.WriteLine($"Successfully moved process {processId} to group {targetGroup}");
            Console.WriteLine($"Previous group: {oldGroupAffinity[0].Group}");
        }
        else
        {
            Console.WriteLine($"SetProcessGroupAffinity failed: {Marshal.GetLastWin32Error()}");
        }

        CloseHandle(hProcess);
        return success;
    }

    // 调用示例
    public static void Main()
    {
        uint targetPid = 1234;
        ushort targetGroup = 1;
        SetProcessToGroup(targetPid, targetGroup);
    }
}
一些关键注意事项
  • 处理器组编号从0开始,可以用GetActiveProcessorGroupCount函数获取当前系统的活跃处理器组数量
  • 打开进程时的权限一定要对应:查询用PROCESS_QUERY_INFORMATION,修改用PROCESS_SET_INFORMATION,也可以直接用PROCESS_ALL_ACCESS(但不推荐,遵循最小权限原则)
  • 64核以上的Windows服务器通常会自动划分多个处理器组,你可以先通过任务管理器的“详细信息” tab,右键进程选择“设置相关性”来查看当前的组和核心分配,验证你的代码结果
  • 有些受保护的系统进程(比如csrss.exe、smss.exe)无法修改,会返回权限不足的错误

内容的提问来源于stack exchange,提问作者evpo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:38:40