Windows自身没有提供类似Linux cgroup的能力来限制进程或进程组的资源占用,进程CPU/IO/内存/网络等资源的控制只能由自己实现。目前已有第三方的实现,主要是限制进程CPU的占用,如文档 < 21 Best Ways to Limit the CPU Usage of a Process > 所描述的BES,Process Tamer等软件。自Windows 8及Server 2012开始Windows系统有提供以job为单位的CPU占用及内存上限设置,之前的版本则只能以进程或线程为单位进行限制。
进程CPU占用限制方案
即时轮询系统所有进程(线程)的CPU占用,当发现所设定进程有超标时强制暂停进程所有线程的执行,然后在适当的时机再恢复执行。其中所涉及技术点:
进程CPU占用查询 GetProcessTimes
BOOL GetProcessTimes(
[in] HANDLE hProcess,
[out] LPFILETIME lpCreationTime,
[out] LPFILETIME lpExitTime,
[out] LPFILETIME lpKernelTime,
[out] LPFILETIME lpUserTime
);
此函数可以获取进程从创建至当前的总运行时间及总的CPU时间,(KernelTime + UserTime) < 系统CPU数 * (当前时间 - CreationTime)
线程CPU占用查询 GetThreadTimes
BOOL GetThreadTimes(
[in] HANDLE hThread,
[out] LPFILETIME lpCreationTime,
[out] LPFILETIME lpExitTime,
[out] LPFILETIME lpKernelTime,
[out] LPFILETIME lpUserTime
);
QueryThreadCycleTime可以提供更精准的CPU时间数据,单位为CPU时钟周期
BOOL QueryThreadCycleTime(
[in] HANDLE ThreadHandle,
[out] PULONG64 CycleTime
);
线程暂停及恢复
Windows平台没有提供暂停整个进程的支持函数,只能以线程为单位来操作,即SuspendThread及ResumeThread:
DWORD SuspendThread(
[in] HANDLE hThread
);
DWORD ResumeThread(
[in] HANDLE hThread
);
CPU亲和性设置: SetProcessAffinityMask
BOOL SetProcessAffinityMask(
[in] HANDLE hProcess,
[in] DWORD_PTR dwProcessAffinityMask
);
此函数可以限定进程及其所有线程所能使用的CPU,故一定程序上亦限定了进程最大的系统CPU占用率。
DWORD_PTR SetThreadAffinityMask(
[in] HANDLE hThread,
[in] DWORD_PTR dwThreadAffinityMask
);
此函数可单独限制特定线程的CPU亲和性。
进程优先级设置: SetPriorityClass
优先级解决的是优先运行及退让CPU的问题,本质上并不能限定CPU占用,只是优先级高于当前任务的忙碌的时候,当前进程会主动退让CPU 线程优先级设置:SetThreadPriority
BOOL SetThreadPriority(
[in] HANDLE hThread,
[in] int nPriority
);
Job Objects
Windows系统提供了Job的概念用以管理多个进程,可以限制Job对象内所有进程及期线程的CPU核心占用、CPU占用及内存分配上限等,均通过SetInformationJobObject来实现,具体的CPU限制由JOBOBJECT_CPU_RATE_CONTROL_INFORMATION管理,内存限制则由JOBOBJECT_EXTENDED_LIMIT_INFORMATION来管理。
BOOL SetInformationJobObject(
[in] HANDLE hJob,
[in] JOBOBJECTINFOCLASS JobObjectInformationClass,
[in] LPVOID lpJobObjectInformation,
[in] DWORD cbJobObjectInformationLength
);
需要注意的是CPU占用设置只有Windows 8及Server 2012之后的版本有效。
CPU Sets
此部分只限定了CPU Affinity属性
实验验证
可以直接利用开源项目go-winjob验证,验证系统Windows 8 x64,go-winjob git repo: https://github.com/kolesnikovae/go-winjob
验证程序
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
unsigned long total = 0, count = 0, i = 0;
while (1) {
if (malloc(1024)) {
total += 1024;
count++;
}
if (!(++i & 4095))
printf("alloc: %u size: %u bytes\n", count, total);
}
}
无限制
在无限制的情况下,此进程会占满一个CPU核心,commit内存总占用达2G

单一进程
在设定CPU上限16%及内存16M上限之后,结果如下:
examples/job_object.go按如下修改:
var limits = []winjob.Limit{
winjob.WithBreakawayOK(),
winjob.WithKillOnJobClose(),
winjob.WithActiveProcessLimit(3),
winjob.WithProcessTimeLimit(10 * time.Second),
winjob.WithCPUHardCapLimit(1600), // 16%
winjob.WithProcessMemoryLimit(16 << 20), // 16MB
winjob.WithWriteClipboardLimit(),
}
const defaultCommand = ".\\CPUStress.exe"
多进程(双进程)
将winjob.WithProcessMemoryLimit 改为 winjob.WithJobMemoryLimit,后者表示此job内所有进程要占用的总内存限制:
var limits = []winjob.Limit{
winjob.WithBreakawayOK(),
winjob.WithKillOnJobClose(),
winjob.WithActiveProcessLimit(3),
winjob.WithProcessTimeLimit(10 * time.Second),
winjob.WithCPUHardCapLimit(1600), // 16%
winjob.WithJobMemoryLimit(16 << 20), // 16MB
winjob.WithWriteClipboardLimit(),
}
验证结果如下:

winjob example代码:
// +build windows
package main
import (
"encoding/json"
"log"
"os"
"os/exec"
"os/signal"
"time"
"golang.org/x/sys/windows"
"github.com/kolesnikovae/go-winjob"
)
var limits = []winjob.Limit{
winjob.WithBreakawayOK(),
winjob.WithKillOnJobClose(),
winjob.WithActiveProcessLimit(3),
winjob.WithProcessTimeLimit(10 * time.Second),
winjob.WithCPUHardCapLimit(1600), // 16%
winjob.WithJobMemoryLimit(16 << 20), // 16MB
winjob.WithWriteClipboardLimit(),
}
const defaultCommand = ".\\CPUStress.exe"
const stressCommand = ".\\CPUStressX64.exe"
func main() {
job, err := winjob.Create("", limits...)
if err != nil {
log.Fatalf("Create: %v", err)
}
cmd := exec.Command(defaultCommand)
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &windows.SysProcAttr{
CreationFlags: windows.CREATE_SUSPENDED,
}
if err := cmd.Start(); err != nil {
log.Fatalf("Start: %v", err)
}
stress := exec.Command(stressCommand)
stress.Stderr = os.Stderr
stress.SysProcAttr = &windows.SysProcAttr{
CreationFlags: windows.CREATE_SUSPENDED,
}
if err := stress.Start(); err != nil {
log.Fatalf("Start: %v", err)
}
s := make(chan os.Signal, 1)
signal.Notify(s, os.Interrupt)
c := make(chan winjob.Notification)
subscription, err := winjob.Notify(c, job)
if err != nil {
log.Fatalf("Notify: %v", err)
}
done := make(chan struct{})
go func() {
defer close(done)
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
var counters winjob.Counters
for {
select {
case <-s:
log.Println("Closing job object")
if err := job.Close(); err != nil {
log.Fatal(err)
}
log.Println("Closing subscription")
if err := subscription.Close(); err != nil {
log.Fatal(err)
}
return
case n, ok := <-c:
if ok {
log.Printf("Notification: %#v\n", n)
} else if err := subscription.Err(); err != nil {
log.Fatalf("Subscription: %v", err)
}
case <-ticker.C:
if err := job.QueryCounters(&counters); err != nil {
log.Fatalf("QueryCounters: %v", err)
}
b, err := json.MarshalIndent(counters, "", "\t")
if err != nil {
log.Fatal(err)
}
log.Printf("Counters: \n%s\n", b)
}
}
}()
if err := job.Assign(cmd.Process); err != nil {
log.Fatalf("Assign: %v", err)
}
if err := winjob.Resume(cmd); err != nil {
log.Fatalf("Resume: %v", err)
}
if err := job.Assign(stress.Process); err != nil {
log.Fatalf("Assign: %v", err)
}
if err := winjob.Resume(stress); err != nil {
log.Fatalf("Resume: %v", err)
}
if err := cmd.Wait(); err != nil {
log.Fatalf("Wait: %v", err)
}
if err := stress.Wait(); err != nil {
log.Fatalf("Wait: %v", err)
}
// Wait for a signal.
<-done
}
We moved during a heat wave— Walnut Creek Movers kept the pace up and protected heat-sensitive items like candles and cosmetics.
Useful advice! For more, visit Denver Pain Management Clinic .
This was quite informative. For more, visit Walters Bar-B-Que .
We arranged a group ride to a family event in Lake Success and it worked seamlessly. Booking link was through North Hempstead vehicle transport .
How To Bet On Horse Races (Bukmacherjakie.Com)
racing results today non runners
I found this very interesting. For more, visit Just Gutters LLC .
Just finished my orthodontic treatment journey with them; couldn’t be happier with the outcome from # # anyKeyword###! Teeth Retainers
Thanks for the great explanation. More info at The Bud Depot .
live horse racing online 2026 guineas ante post betting
Valuable information! Find more at youtube mp3 converter .
Great job! Discover more at Foothills Paving Co .
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
Useful advice! For more, visit Winslow NYC .
GO99 là website nội dung tổng hợp được phát triển theo hướng gọn gàng, dễ đọc và có sự phân chia chủ đề khá rõ ràng xoay quanh GO99 GO99
We relocated from North Scottsdale to Austin. Pickup windows can be wide, but good communication helped. The company I found via Scottsdale car shippers gave real-time driver updates.
Chuyên mục casino GO99 được triển khai theo kiểu gom nhóm nội dung cùng chủ đề, tạo cảm giác như một khu vực riêng biệt dành cho người quan tâm đến mảng này. Cách sắp xếp tương đối rõ ràng giúp việc đọc và lướt nội dung trở nên thuận tiện hơn. Casino GO99
The safety features on modern electric gates are impressive! It’s great to see technology advancing. Turnstiles Rotherham
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
pokie machine laws canada, 888 poker withdrawal united states and usa free bingo prize, or roulette online Big Small casino game Strategy australia
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
Thanks for the thorough article. Find more at car detailing .
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
Can you share more about the tools needed for floor restoration? I’m ready to dive in! Commerical Flooring
Trang khuyến mãi GO99 trên Qxinada tập trung vào việc tổng hợp các ưu đãi theo hướng dễ theo dõi, phù hợp với người dùng muốn cập nhật nhanh thông tin mà không cần đọc quá nhiều Khuyến mãi GO99
Great insights on orthodontics! I’ve been looking for options in Dunfermline. Invisible Braces
I appreciate the reminder that consent includes discussing alternatives like skincare and lasers. Our comparison chart is at botox .
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
I love how you explained the importance of hydration for skin care. It’s so crucial! For more insights, visit beauty salon barnsley .
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
1вин официальный [url=https://1win43592.help]https://1win43592.help[/url]
lucky jet 1win [url=https://www.1win25340.help]https://www.1win25340.help[/url]
It’s refreshing to see such a thorough exploration of both sides of the workers’ compensation debate! ## car accident lawyer
Gem88 tự hào xác lập vị thế là hệ thống cá cược thể thao uy tín số 1 tại thị trường Việt Nam năm 2026 gem88
1win как пополнить баланс [url=1win25340.help]1win25340.help[/url]
1вин установить приложение [url=1win43592.help]1win43592.help[/url]
This was very insightful. Check out Taxi Arzúa for more.
I liked this article. For additional info, visit abogada Vigo .
Valuable information! Find more at reservar albergue Palas de Rei .
Great insights on the evolving cannabinoid industry! For any individual scaling formulations or vape manufacturing, sourcing reliable bulk HHC distillate is prime—seek providers who post full-panel COAs (residual solvents, heavy metals get redirected here
Nіce post. I was checking continuously this weblog and I’m inspired!
Very useful information specifically the remaining part :
) I deal with such information a lot. I used tto bе seeking this certain info for a very
lengthy time. Thanks and best of luck.
Here іis my page – راهنمای کامل ثبت نام در سایت بازی انفجار
I love how friendly the staff is at my orthodontist’s office in Livingston! They made me feel so comfortable! Invisible Braces
Valuable information! Discover more at exterior detailing .
As a landlord, I value thoroughness. Annual inspections by home inspection reduce vacancy headaches.
Thanks for the useful suggestions. Discover more at elderly care .
Great point about creating a safe home environment—labeling drawers and using contrasting colors really helps. We used a checklist from senior care to get started.
Thanks for the insightful write-up. More like this at senior care .
1win минимальная сумма депозита элсом [url=https://1win43592.help/]https://1win43592.help/[/url]
1win киргизче жүктөп алуу [url=https://1win25340.help/]https://1win25340.help/[/url]