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
}
I really appreciate the focus on noticing the early physical signs rather than waiting for a full-blown explosion. I never realized how much tension I carry in my clenched jaw until I started paying attention during my commute https://www.4shared.com/s/fNbRRYtksjq
Thanks for the clear breakdown. Find more at Kerner Injury Law Group .
Your LED flicker troubleshooting guide is a keeper. I add brand notes on residential electrician Irving .
I feel your pain on this. Navigating the market as a small business with under 50 employees is honestly exhausting. We looked into switching plans recently, but the costs keep climbing every year https://aged-wiki.win/index.php/How_Does_an_ICHRA_Monthly_Allowance_Work_for_Employees%3F_A_Guide_for_Small_Business_Owners
J’adore le concept Huttopia, surtout pour la localisation. Nous avons testé celui près du lac de Serre-Ponçon l’été dernier et l’accès direct à l’eau est vraiment un immense atout descente de la Clarée en kayak
This article really hit home for me. Living in a busy place like Vancouver can be so draining, and I never realized how much my constant clenched jaw was a sign of built-up tension Extra resources
This is such a helpful breakdown. People often overlook the recurring expenses like grooming, which really adds up when you’re paying £50 every six weeks just to keep a dog’s coat manageable how much to save for puppy
We are currently prepping for a big trade show next month and honestly, this post hit home. We decided to go with high-quality hoodies for our booth staff this time around instead of standard tees staff uniform branding
Helpful suggestions! For more, visit Paver Installation Dix Hills NY .
Thanks for breaking this down. It can be so overwhelming trying to pick a clinic around Mont Kiara with all the options out there. I really appreciate the tip about asking exactly who performs the injectables questions about laser recovery
Finding affordable plans for my team of under 50 employees has been a total headache this year. We keep seeing premiums climb higher, and it’s getting tough to stay competitive while keeping our overhead manageable tax credits SHOP
I snatch the provider handbook torque tables from brake service in Greensboro anytime.
I deal with this every single day in the shop. You simply cannot fix these newer vehicles without proper diagnostic software module communication
Merci pour cet article, ça donne vraiment envie de s’évader. Nous avons adoré notre séjour près du lac de Serre-Ponçon l’été dernier https://canvas.instructure.com/eportfolios/4111572/home/what-to-do-if-you-suspect-medical-malpractice-in-los-angeles
I really appreciated this take on local stress levels. I often catch myself with a clenched jaw while commuting through downtown traffic, and I never realized that was a physical sign of my rising frustration how to calm down fast
We are currently prepping for a big trade show next month and this article really hits home. We decided to go with bulk apparel for our booth staff to keep everyone looking consistent and professional merchandise t shirts for influencers
This is such a helpful breakdown! It’s so easy to overlook the recurring expenses until you’re already in it. For me, the grooming costs at £45 every six weeks really add up over a year Helpful hints
I have been researching clinics around Mont Kiara lately and it can feel a bit overwhelming with so many options. Your point about checking credentials really resonated with me https://aged-wiki.win/index.php/What_Should_a_Clinic_Explain_Before_Facial_Contouring_Treatments%3F
Finding affordable coverage as a small business with under 50 employees feels like a full-time job in itself. We keep seeing our premiums jump, and it’s getting difficult to balance quality benefits with our bottom line level funded health plan
I see this every day in the shop. You honestly cannot fix these modern cars without diagnostic software anymore. Basic scan tools fail once you hit a complex ADAS calibration or a module programming task Check out the post right here
J’adore l’ambiance des campings Huttopia, c’est toujours très relaxant. Nous avons testé celui près du lac de Serre-Ponçon l’été dernier et c’était magnifique https://escatter11.fullerton.edu/nfs/show_user.php?userid=9689325
I liked this article. For additional info, visit Omni Dental Specialists .
This really hits home. We often forget the hidden expenses until they pile up. My golden retriever needs professional grooming every eight weeks at £50 a pop, and it definitely adds up over the year breeder puppy price uk
Thanks for the breakdown. I have been looking at a few spots around Mont Kiara and it is definitely overwhelming. One thing I learned from this post is to specifically ask who exactly performs the injectables instead of assuming it is always the doctor https://pastelink.net/n4elcvkm
Remember that insurance adjusters are not on your side; that’s why hiring a car accident lawyer is crucial for fair treatment.
Appreciate the helpful advice. For more, visit Kerner Law Group PLLC .
For contractors who handle both decks and patios around Chicago, check wave outdoors decks mount prospect .
Finding affordable coverage for my team of under 50 employees has been a constant struggle. We currently pay over $2,000 per month for family coverage, and the costs just keep climbing every year https://pin.it/4P6WsEEy1
Appreciate the detailed information. For more, visit Angels haven care assisted living .
I have been researching a few places around Mont Kiara lately and it is definitely overwhelming. Your point about checking the practitioner’s credentials really resonated with me skin analysis for better results
J’adore l’ambiance des campings Huttopia, surtout pour le calme. On a testé celui près du lac de Serre-Ponçon l’été dernier et c’était magnifique Aller sur ce site
I really appreciate the focus on noticing the early physical signs of stress. I used to wait until I was at my breaking point to do anything about it, but now I try to pay attention when my jaw starts to clench Website link
Appreciate the breakdown of fault versus liability. I found out extra about it when I contacted Accident Lawyer .
We are actually gearing up for a big trade show next month and just ordered our first round of branded polos for the team. It really helps everyone look professional and unified on the floor https://5fcu7.stick.ws/
You nailed it with this article. I see guys every day trying to bypass the scan tool, but you just cannot fix modern cars without looking at live data. It saves so much time during the diagnostic process real time sensor data
Appreciate the detailed information. For more, visit Angels haven care assisted living .
I have been researching a few places around Mont Kiara lately and it is definitely overwhelming. Your point about checking who performs the injectables is so important. I think a lot of people forget to ask if it is a doctor or a nurse doing the procedure https://www.protopage.com/kevin-holt11#Bookmarks
Families should tour both options and ask about staffing ratios, secure doors, and behavior plans. Good checklist at elderly care .
This is such a helpful breakdown. We always budget for food, but those boarding costs really add up. We pay around £40 a day for our pup when we go away, which is definitely the biggest surprise in our yearly expenses https://x5h8s.stick.ws/
Modern cars demand these diagnostic tools every single day. I struggle when a generic scan tool fails to perform a simple steering angle sensor calibration after an alignment Website link
Loved the part about preserving vehicle data. EDR info at Truck Accident Attorney .
Thanks for the detailed post. Find more at casa rural cerca de Segovia capital .
They disassembled and reassembled furniture swiftly. Hired due to moving services santa cruz .
Great insights! Find more at assisted living .
תובנות זהב. יש קובץ עוגנים לדוגמא לפי ענפים שונים ב- בניית אתרים .
The list you shared is place on. We utilized a similar list from elderly care to assess communities prior to devoting.
Every story shared about successful restorations encourages others not just locally but across communities worldwide. office floor repair
This post nails it. Consistency across Google Business profiles is huge—learned that while doing local marketing in san jose. digital marketer
plinko официальный сайт ios [url=https://plinko47590.help]https://plinko47590.help[/url]
Well done! Find more at marketing consultant near me .