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
}
Thanks for the inspiration on creating cozy outdoor spaces; perfect timing as summer approaches here in Southfield MI! Find additional ideas at Home improvement services Southfield MI !
Southern California is leading the way in renewable energy with commercial solar solutions! commercial solar in southern california
Appreciate the detailed post. Find more at memory 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.
Wow, fantastic weblog structure! How lengthy have you been running a blog for? you make running a blog glance easy. The overall look of your site is wonderful, as well as the content!
在线购买他达拉非片用于肛交XXX色情
Your comprehensive guide on roofing contracts is fantastic; I’m eager to see what Roof Repair Services Illinois offers
Fantastic resource here on choosing quality roofing services—I’ll be sure to visit roof repair in illinois
Современный мир высоких технологий предлагает большое разнообразие вариантов регистрации доменных имен. Среди популярных сочетаний выделяется простая и выразительная комбинация `slon1`. Именно такая последовательность стала основой множества доменных адресов, привлекающих внимание пользователей. Простота восприятия делает её идеальной для брендов и веб-ресурсов различного назначения.
[url=https://slon14c.cc]slon3.at [/url]
Одним из интересных направлений стало использование национального домена верхнего уровня (.cc). Таким образом появилось популярное сочетание **slon1.cc**, которое сочетает простую и доступную ассоциацию со словом «слон» и одновременно обозначает принадлежность ресурса к определённой географической зоне. Такое решение способствует быстрому восприятию и идентификации сайта пользователями.
[url=https://slon4cc.com]ссылка на кракен телеграм [/url]
Еще одним вариантом стал вариант **slon1.at**, в котором подчеркнута связь с австрийским сегментом сети Интернет. Такой выбор тоже имеет свою специфику и добавляет дополнительные смыслы в восприятие бренда. Благодаря своим уникальным характеристикам этот тип домена активно используется компаниями, ориентированными на европейский рынок.
[url=https://slon7-at.com]slon3 at [/url]
Часто владельцы ресурсов выбирают и сокращённую форму записи своего имени. К примеру, такое написание, как **slon1cc**, придаёт сайту дополнительный шарм и облегчает процесс запоминания. Подобная форма часто встречается в международной практике брендирования и отражает общую тенденцию упрощения структуры именования.
[url=https://slon2-cc.com]kraken даркнет рынок ссылки [/url]
В заключение отметим ещё одну разновидность написания домена — **slon1сс**. Здесь упор сделан на двойное повторение буквы «с», что создаёт особое звучание и запоминающийся эффект. Такая игра букв усиливает привлекательность домена и выделяет ресурс среди прочих аналогичных предложений.
[url=https://at-slon5.cc]ссылка на кракен официальный [/url]
https://slonl1.cc
slon7 cc
The checklist for DIY vs pro help is smart. I matched it with advice from winnipeg bathroom renovations .
The application of 3D printing technology in tissue engineering is mind-blowing—learn more about it through ## any Keyword # # ! Ketamine Infusion Therapy orange county
Лечебный процесс организуется таким образом, чтобы каждый этап логически дополнял предыдущий и формировал устойчивую динамику. Это позволяет избежать резких изменений состояния и поддерживать медицинскую безопасность.
Подробнее – [url=https://narkologicheskaya-klinika-v-rnd19.ru/]анонимная наркологическая клиника в ростове-на-дону[/url]
Went keyless at our Houston Airbnb using Car key replacement to set up codes and audit trail.
Thanks for the helpful article. More like this at assisted living .
Sharing insights regarding sustainable practices could elevate building standards throughout California significantly long term !# # anyKeyWord ## Los Angeles kitchen Remodeling
Nutrition often gets overlooked in memory care. Finger foods and high-calorie smoothies have helped us maintain weight. Meal planning tips from respite care were very useful.
Современный мир высоких технологий предлагает большое разнообразие вариантов регистрации доменных имен. Среди популярных сочетаний выделяется простая и выразительная комбинация `slon1`. Именно такая последовательность стала основой множества доменных адресов, привлекающих внимание пользователей. Простота восприятия делает её идеальной для брендов и веб-ресурсов различного назначения.
[url=https://slon2-at.net]кракен список ссылок и зеркал [/url]
Одним из интересных направлений стало использование национального домена верхнего уровня (.cc). Таким образом появилось популярное сочетание **slon1.cc**, которое сочетает простую и доступную ассоциацию со словом «слон» и одновременно обозначает принадлежность ресурса к определённой географической зоне. Такое решение способствует быстрому восприятию и идентификации сайта пользователями.
[url=https://at-slon10.cc]slon8.at [/url]
Еще одним вариантом стал вариант **slon1.at**, в котором подчеркнута связь с австрийским сегментом сети Интернет. Такой выбор тоже имеет свою специфику и добавляет дополнительные смыслы в восприятие бренда. Благодаря своим уникальным характеристикам этот тип домена активно используется компаниями, ориентированными на европейский рынок.
[url=https://slonl3.cc]какая ссылка на кракен [/url]
Часто владельцы ресурсов выбирают и сокращённую форму записи своего имени. К примеру, такое написание, как **slon1cc**, придаёт сайту дополнительный шарм и облегчает процесс запоминания. Подобная форма часто встречается в международной практике брендирования и отражает общую тенденцию упрощения структуры именования.
[url=https://slon8-at.com]кракен вход ссылки [/url]
В заключение отметим ещё одну разновидность написания домена — **slon1сс**. Здесь упор сделан на двойное повторение буквы «с», что создаёт особое звучание и запоминающийся эффект. Такая игра букв усиливает привлекательность домена и выделяет ресурс среди прочих аналогичных предложений.
[url=https://slon1-at.net]slon5 at [/url]
https://slon1-at.net
slon10.at
I find out how much I needed to do to get the stunning lawn and backyard I always desired. The guidance below is invaluable. Thank you for sharing. landscaping
Solar power is the future, especially for businesses looking to save on utility costs! Direct solar installer southern california
This is very insightful. Check out senior care for more.
This post reminded me to review contracts carefully. senior care has tips on red flags and what to negotiate.
Thanks for the useful suggestions. Discover more at assisted living .
Panelmålning och kvistlack i sommarstugan löst genom https://www.bookmarks4all.win/vara-malare-stockholm-tar-hansyn-till-allergier-och-doftoverkanslighet-genom-att-valja-lagluktande .
Die Tipps haben mir beim Umzug nach Zürich sehr geholfen. Unser Reinigungsteam war Umzugsreinigung .
The piece on keyword density myths debunks commonplace error; examine greater at web design companies near me .
It’s encouraging watching individuals regain mobility after utilizing resources provided via textbf#allaboutregeneration!” Pain Management Scottsdale
Regenerative medicine is truly the future of healthcare! Excited to see advancements in regenerative medicine orange county .
Thanks for the great explanation. Find more at campamentos cerca de mí .
регистрация бк все про новости спорта и матчи читайте онлайн на bkcloude.ru
Loved reading about creative storage solutions—perfect for maximizing space in any small houses around Southfield MI! Visit Metal roof installation Southfield MI for further inspiration!
This was highly educational. For more, visit respite care .
Such practical advice regarding roof installation processes; eager to connect with Roof Replacement Company In Illinois
Inspirerende renovatieprojecten in Gent, bedankt voor het delen. Zie ook ##Rivage Travel##. dakwerken gent
Appreciate the tips on seasonal maintenance! Will connect with Roofing Services In Illinois to ensure my roof is ready for winter.
”How important do you view accessibility becoming here shortly within scope concerning alternative practices emerging recently? Eager hearing perspectives offered up stemming directly back furthermore linked tightly together aligned clearly revealed back pain specialist scottsdale
Если нужен срочный электрик, советую https://electrics-mos.ru, мне помогли в день обращения
Статья посвящена душевым стойкам Damixa: рассматриваются варианты исполнения, высота, тип верхнего душа, ручная лейка, переключение режимов и особенности установки. Такой разбор помогает выбрать модель, которая подойдет по стилю, напору воды и удобству ухода: https://santexnik-market.ru/dush/dushevye-stojki-damixa/
Thanks for explaining roof pitch and safeguard. I hired insured execs from licensed roofing company for the task.
Pet-friendly policies were important for my mom. memory care helped identify assisted living homes that welcome pets.
This was highly educational. For more, visit senior care .
The carousel and content material playing cards experience polished and handy. web designer (NEVER TRANSLATE IT)
Truly appreciate how informative this blog has been thus far shedding light upon lesser-known facts surrounding building codes regulations affecting properties located nearby ensuring every homeowner remains compliant protecting investments made wisely – Deck installation Southfield MI
This was a wonderful guide. Check out elderly care for more.
Great point about creating a safe home environment—labeling drawers and using contrasting colors really helps. We used a checklist from elderly care to get started.
Can’t wait to see how many businesses adopt commercial solar solutions in the coming years! EV charging station installation company
Thanks for sharing such a comprehensive, practical pest control guide Tauranga pest control
Thanks for the comprehensive read. Find more at elderly care .
Appreciate the useful tips. For more, visit respite care .
Los Angeles home builders are definitely setting trends that other cities will follow for years to come! Los Angeles kitchen Remodeling
Appreciate all these insights into contracting; very useful as I’m considering roof repairs—thank you, Roofing Services In Illinois
When some one searches for his essential thing, therefore he/she
wants to be available that in detail, thus that thing is maintained over here.