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
}
Windsor Ontario readers will realise the reasonable steps here—hyperlink as a result of waterproofing windsor ontario .
Appreciate the insightful article. Find more at commerical movers .
Helpful point about how car modifications (lift kits, tires) can affect liability or damages arguments. car accident lawyer
“Every time I think about summer parties, I remember that epic waterslide we rented from that place in Tampa—it was unforgettable!” # # anyKeword #” Bounce Genie Tent Rentals
Looking for reliable deck contractors in the Chicago area — found great options here deck contractors mount prospect il .
I found this very interesting. Check out web design agency san jose for more.
Exceptional Service: Tampa Bay Pressure Washing exceeded my expectations with their prompt and professional service. From the moment I contacted them, their team was responsive and eager to assist. roof cleaning cost
Your reminder to avoid mind-reading is crucial. acupuncture treatment cost taught us to ask, not assume.
1win-ug [url=https://www.1win54316.help]https://www.1win54316.help[/url]
Excellent breakdown of Google’s ranking factors! I’ve explored some more at AI operations automation .
กำลังมองหาไฟหน้าโปรเจคเตอร์สวยๆ ตัดเส้นคม ไม่แยงตา ใครมีร้านแนะนำฝากลิงก์ไว้ที่ ร้านเปลี่ยนหลอดไฟรถยนต์ ใกล้ฉัน หน่อยครับ
I definitely feel the struggle with these rising costs. Managing a team with under 50 employees makes finding affordable plans feel impossible, especially when the quotes keep climbing every year multi state provider networks
This article toenails the ecological conveniences. foundation repair sustains low-impact installs.
Great advice on dealing with property damage. Guidance at Injury Lawyer .
Great info on backup generators; sizing help at local Garland electrician services .
“The evolution of identity management as part of broader security strategies has come so far—it would be great to read about innovations through %%ANYKEYWORD%%.” professional access control installation
I appreciate your emphasis on ethical practices in real estate; it’s crucial for trust building! top real estate agents
For doorbell transformer upgrades with smart cams, Scottsdale Tempe Mesa Chandler electrician matched voltage and VA perfectly.
Finding the right plan for my team of under 50 employees has been a total headache lately. The costs just keep climbing every year, and it feels like we are constantly choosing between affordability and quality care individual coverage HRA
שווה להציע ערכי-מוסף לקהילה בתמורה לקישור. מדריך בחינם הפנה ל- בניית אתרים לעסקים .
I didn’t want court, but being ready to sue increased the offer. Lawyer advantage. Info: car accident lawyer .
Merci pour cet article qui donne vraiment envie de partir ! Nous avons adoré le site de Serre-Ponçon l’été dernier pour son accès direct au lac sejour glamping Huttopia Lac Serre-Ponçon
For clean panels, Richardson, TX electrical services Richardson teaches wire management with lacing and ID sleeves.
Finding affordable coverage for my team of under 50 employees has been a total headache this year. We keep seeing rates climb, and it makes it so hard to compete for talent against the big guys https://richard-grant3.raindrop.page/bookmarks-69865115
J’adore l’ambiance des campings Huttopia, surtout pour le calme en pleine nature. Nous avons adoré celui de Serre-Ponçon pour l’accès direct au lac, c’est vraiment idéal pour se baigner cliquez ici
I just finished stocking up on bulk gear for our upcoming trade show booth, and this post hit home. We went with a simple logo print on high-quality hoodies because comfort usually leads to staff actually wearing them again seasonal demand apparel stock
Appreciate the comprehensive advice. For more, visit youtube to mp3 fast .
We are currently prepping for a big trade show and this really helped me think about our booth setup. We decided to stick with a high-quality cotton blend for our staff shirts so the team stays comfortable all day last minute order tees launch
J’adore l’ambiance des Huttopia en Provence ! C’est vraiment le top pour se déconnecter. Est-ce que l’accès au lac de Serre-Ponçon est facile à pied depuis le camping en haute saison ? J’hésite à réserver pour cet été avec les enfants location chalet bois Hautes-Alpes
This really hit home for me. People often forget about those hidden expenses like professional grooming. I’m currently paying £45 every six weeks for my spaniel, and it definitely adds up over a year vaccinations microchipping neutering cost uk
I really appreciated this take on local stress. Living in Vancouver can be so fast-paced, and I often catch myself with a clenched jaw while stuck in traffic or navigating the busy streets anger counselling Vancouver
Appreciate the comprehensive insights. For more, visit Injury Recovery & Wellness Center .
This was quite helpful. For more, visit Injury Recovery Centre .
We are currently prepping for a big trade show next month and this article hit the nail on the head. We decided to go with high-quality hoodies for our staff this year because they actually look professional and hold up well bulk apparel for events
This is such a helpful breakdown. People really underestimate the recurring bills, especially the grooming costs. I’m currently paying £50 every six weeks for my spaniel, and it definitely adds up over the year https://cruzinnp079.tearosediner.net/the-real-cost-of-dog-ownership-beyond-the-instagram-feed
I really resonated with the point about staying aware of a clenched jaw. I always thought anger was just about the big explosions, but noticing that physical tension early on has been a game-changer for me men’s counselling Vancouver
Great job! Find more at casas rurales para grupos Segovia .
HD-laatu ja nopeat latausajat ratkaisevat. Vertailin muutamaa palvelua ja sain yllättävän hyviä mittauksia lähteestä chat-alustat – kannattaa tsekata ennen tilaamista.
I really appreciated this take on local resources. The part about recognizing the clenched jaw as an early warning sign was a huge eye-opener for me. I often ignore those physical signals until I am already way too stressed out tight shoulders stress treatment
1win сайт [url=www.1win43592.help]1win сайт[/url]
I’ve been checking out a few spots around Mont Kiara lately and it can be pretty overwhelming to choose the right one. Your point about checking the practitioner’s credentials is so important recovery time after laser
That breakdown really puts things into perspective. We always forget about the smaller extras until the bill hits. I was shocked to realize our grooming sessions every six weeks now average £50 a pop. It definitely adds up fast dog boarding cost per day uk
1win валюта аккаунта [url=https://1win25340.help/]1win валюта аккаунта[/url]
I completely agree with this take. You simply cannot fix modern cars without solid diagnostic software anymore. Basic scan tools just miss way too much, especially when I need to look at live data streams to hunt down intermittent electrical gremlins Visit this page
1вин кыргызча катталуу [url=www.1win43592.help]www.1win43592.help[/url]
1win киргизче кирүү [url=https://1win25340.help/]https://1win25340.help/[/url]
Great mention of portraits showing skid marks and particles. I used a graphic manual from Motorcycle Accident Lawyer .
Для Воронежа выездной формат особенно востребован вечером, ночью и ранним утром, когда у больного резко усиливаются симптомы и поездка в медицинское учреждение становится тяжёлой или просто нереальной. Если человек несколько дней употреблял алкоголь, почти не спал, плохо переносит воду, жалуется на сердцебиение и слабость, то откладывать осмотр не стоит. Срочная наркологическая помощь нужна именно тогда, когда ситуация развивается быстро, а семья уже видит, что своими силами справиться не удаётся. Врач приезжает, проводит осмотр, определяет, нет ли признаков осложнений, и уже на месте решает, какие меры допустимы дома, а какие требуют другого формата оказания помощи.
Разобраться лучше – [url=https://narkolog-na-dom-voronezh-3.ru/]запой нарколог на дом воронеж[/url]
I agree completely. You just can’t touch a modern engine without high-end diagnostic software anymore. Basic code readers leave you blind when you need to view live data streams to hunt down intermittent misfires ECU flashing and coding guide
This was nicely structured. Discover more at Kerner Law Group PLLC .