Windows进程CPU、内存等资源限制

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 &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

void main(int argc, char *argv[])
{
        unsigned long total = 0, count = 0, i = 0;

        while (1) {
                if (malloc(1024)) {
                        total += 1024;
                        count++;
                }
                if (!(++i &amp; 4095))
                        printf(&quot;alloc: %u size: %u bytes\n&quot;, count, total);
    }
}

无限制

在无限制的情况下,此进程会占满一个CPU核心,commit内存总占用达2G CPUStress unlimited

单一进程

在设定CPU上限16%及内存16M上限之后,结果如下: CPUStress single process 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 &lt;&lt; 20), // 16MB
        winjob.WithWriteClipboardLimit(),
}

const defaultCommand = &quot;.\\CPUStress.exe&quot;

多进程(双进程)

将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 &lt;&lt; 20), // 16MB
        winjob.WithWriteClipboardLimit(),
}

验证结果如下: CPUStress 2-processes CPUStress 2-processes

winjob example代码:

// +build windows

package main

import (
        &quot;encoding/json&quot;
        &quot;log&quot;
        &quot;os&quot;
        &quot;os/exec&quot;
        &quot;os/signal&quot;
        &quot;time&quot;

        &quot;golang.org/x/sys/windows&quot;

        &quot;github.com/kolesnikovae/go-winjob&quot;
)

var limits = []winjob.Limit{
        winjob.WithBreakawayOK(),
        winjob.WithKillOnJobClose(),
        winjob.WithActiveProcessLimit(3),
        winjob.WithProcessTimeLimit(10 * time.Second),
        winjob.WithCPUHardCapLimit(1600),    // 16%
        winjob.WithJobMemoryLimit(16 &lt;&lt; 20), // 16MB
        winjob.WithWriteClipboardLimit(),
}

const defaultCommand = &quot;.\\CPUStress.exe&quot;
const stressCommand  = &quot;.\\CPUStressX64.exe&quot;

func main() {
        job, err := winjob.Create(&quot;&quot;, limits...)
        if err != nil {
                log.Fatalf(&quot;Create: %v&quot;, err)
        }

        cmd := exec.Command(defaultCommand)
        cmd.Stderr = os.Stderr
        cmd.SysProcAttr = &amp;windows.SysProcAttr{
                CreationFlags: windows.CREATE_SUSPENDED,
        }
        if err := cmd.Start(); err != nil {
                log.Fatalf(&quot;Start: %v&quot;, err)
        }

        stress := exec.Command(stressCommand)
        stress.Stderr = os.Stderr
        stress.SysProcAttr = &amp;windows.SysProcAttr{
                CreationFlags: windows.CREATE_SUSPENDED,
        }
        if err := stress.Start(); err != nil {
                log.Fatalf(&quot;Start: %v&quot;, 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(&quot;Notify: %v&quot;, 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 &lt;-s:
                                log.Println(&quot;Closing job object&quot;)
                                if err := job.Close(); err != nil {
                                        log.Fatal(err)
                                }
                                log.Println(&quot;Closing subscription&quot;)
                                if err := subscription.Close(); err != nil {
                                        log.Fatal(err)
                                }
                                return

                        case n, ok := &lt;-c:
                                if ok {
                                        log.Printf(&quot;Notification: %#v\n&quot;, n)
                                } else if err := subscription.Err(); err != nil {
                                        log.Fatalf(&quot;Subscription: %v&quot;, err)
                                }

                        case &lt;-ticker.C:
                                if err := job.QueryCounters(&amp;counters); err != nil {
                                        log.Fatalf(&quot;QueryCounters: %v&quot;, err)
                                }
                                b, err := json.MarshalIndent(counters, &quot;&quot;, &quot;\t&quot;)
                                if err != nil {
                                        log.Fatal(err)
                                }
                                log.Printf(&quot;Counters: \n%s\n&quot;, b)
                        }
                }
        }()

        if err := job.Assign(cmd.Process); err != nil {
                log.Fatalf(&quot;Assign: %v&quot;, err)
        }
        if err := winjob.Resume(cmd); err != nil {
                log.Fatalf(&quot;Resume: %v&quot;, err)
        }

        if err := job.Assign(stress.Process); err != nil {
                log.Fatalf(&quot;Assign: %v&quot;, err)
        }
        if err := winjob.Resume(stress); err != nil {
                log.Fatalf(&quot;Resume: %v&quot;, err)
        }

        if err := cmd.Wait(); err != nil {
                log.Fatalf(&quot;Wait: %v&quot;, err)
        }
        if err := stress.Wait(); err != nil {
                log.Fatalf(&quot;Wait: %v&quot;, err)
        }

        // Wait for a signal.
        &lt;-done
}

参考链接

  1. 21 Best Ways to Limit the CPU Usage of a Process
  2. MSDN: Windows Process and Thread Functions
  3. MSDN: CPU Sets
  4. GetThreadTimes

96,521 条评论

  1. Free ladyboy videos and images that will give even the most ardent
    enthusiasts periods of heavenly delight. The most luscious
    and horniest transvestites that enjoy performing in front of cams
    are featured in free ladyboy galleries. A massive ladyboy movie series with lots of
    exclusive, high-quality content. You won’t find any another ladyboy porn anywhere else on the web, which is
    a lot of ladyboy movie. arcviewproperties.com/author/janiclimpson6/ https://directoriomipymes.com/author-profile/alissawhite771/

  2. TIP88 là nền tảng cá cược trực tuyến hiện đại, cung cấp đa dạng trò chơi giải trí như casino trực tiếp, slot game, bắn cá và cá cược thể thao bbc

  3. Публикация знакомит читателей с различными подходами к реабилитации. От традиционных методов до современных программ — вы узнаете, как выбрать оптимальный путь к выздоровлению и преодолеть препятствия на этом пути.
    Не упусти шанс – [url=https://chelnyhools.ru/lechenie-alkogolizma-v-kurske-puti-k-vyzdorovleniju/]clinica plus в курске[/url]

  4. Медицинская публикация представляет собой свод актуальных исследований, экспертных мнений и новейших достижений в сфере здравоохранения. Здесь вы найдете информацию о новых методах лечения, прорывных технологиях и их практическом применении. Мы стремимся сделать актуальные медицинские исследования доступными и понятными для широкой аудитории.
    Получить профессиональную консультацию – [url=https://modnuesovetu.ru/zabolevaniya/prazdniki-bez-posledstvij-nauchno-obosnovannye-metody-detoksikaczii-i-vosstanovleniya-organizma-v-domashnih-usloviyah.html]наркологи самары[/url]

  5. Здравствуйте!
    Текст6: University of Masherova in Vitebsk offers a variety of educational programs in the fields of arts, humanities, and natural sciences. Students have the opportunity to receive a quality education using modern teaching methods and infrastructure. The university actively supports students’ scientific and cultural initiatives, promoting their creative and professional development.
    Полная информация по ссылке – https://vsu.by/en/university/feedback-graduates.html
    Выпускники ВГУ Витебск, FACULTY BELARUS, видео витебск
    ENGLISH-LANGUAGE MASTER’S PROGRAMMES, [url=https://vsu.by/inostrannym-abiturientam/vypuskniki.html]Знакомство Р’РіСѓ студенты[/url], СЃРєРёРґРєРё
    Удачи и успехов в учебе!

  6. You possibly get some pictures scurry through your brain when I tell you that BlackTube is a
    free tube dedicated to bad bitches. These girls are bad in the traditional porno way, for one thing, because they double fist with a couple of girls in a group scene, get pounded up the
    ass by a thick, pulsing BBC, and do all kinds of crap your mommy told you nice girls don’t do.

    HOT https://www.lizyum.com/@bridgetmontero

  7. Aiyah, primary mathematics educates practical ᥙѕes ⅼike budgeting, so guarantee yоur child gets that
    properly bеginning young.
    Eh eh, composed pom pi pi, math is one in the һighest
    subjects during Junior College, laying foundation fоr A-Level advanced math.

    Tampines Meridian Junior College, fгom a dynamic merger,
    supplies innovative education іn drama and Malay language electives.
    Innovative centers support diverse streams, consisting ᧐f commerce.
    Skill advancement ɑnd overseas programs foster management annd cultural awareness.

    А caring community encourages empathy ɑnd strength.

    Trainees аre successful in holistic advancement, prepared fߋr international obstacles.

    Anglo-Chinese Junior College acts аs an excellent model օf
    holistic education, perfectly integrating ɑ
    challenging scholastic curriculum ԝith ɑ caring Christian foundation tһɑt
    supports moral worths, ethical decision-mаking, and
    a sense of function іn every student.
    Tһe college iѕ equipped with advanced infrastructure, including contemporary lecture theaters, ѡell-resourced art studios, ɑnd hiցh-performance sports complexes, ԝhегe
    skilled teachers guide students tο accomplish impressive results in disciplines ranging from the
    liberal arts to the sciences, typically earning national and worldwide awards.
    Students ɑrе encouraged to get involved
    іn a rich range of after-school activities, sᥙch
    ɑs competitive sports teams tһat develop physical endurance аnd
    team spirit, along with performing arts ensembleds tһat cultivate creative expression ɑnd cultural appreciation, ɑll adding tօ
    a balanced lifestyle filled ѡith passion and discipline.
    Throᥙgh tactical global collaborations, consisting ᧐f student
    exchange programs witһ partner schools abroad ɑnd participation in international
    conferences, the college imparts ɑ deep understanding of varied cultures аnd worldwide
    concerns, preparing learners tߋ navigate аn increasingly interconnected woгld with
    grace ɑnd insight. The remarkable performance history оf its alumni, ѡho master leadership roles ɑcross industries likе
    service, medicine, and tһе arts, highlights Anglo-Chinese Junior College’ѕ profound
    influence in developing principled, innovative leaders ԝһo make positive effeсt on society at
    bіg.

    Alas, ԝithout solid math ɑt Junior College, eѵеn prestigious institution children ⅽould falter іn secondary algebra,
    ѕ᧐ deveslop it ρromptly leh.
    Hey hey, Singapore folks, mathematics proves ρrobably tһe extremely impօrtant primary topic, fostering innovation tһrough issue-resolving in innovative careers.

    Ꭰon’t take lightly lah, link ɑ good Junior College pⅼᥙs maths excellence to ensure elevated A Levels scores аnd seamless сhanges.

    Oh, mathematics is the groundwork pillar оf primary
    education, helping children fоr dimensional analysis fߋr design careers.

    Listen սp, Singapore parents, mathematics remains likely the
    highly crucial primary topic, fostering creativity fߋr prⲟblem-solving f᧐r groundbreaking jobs.

    Ꭰon’t take lightly lah, combine ɑ reputable
    Junior College ᴡith maths proficiency fⲟr assure һigh Ꭺ Levels reѕults as wеll as smooth
    transitions.

    Math equips ʏou for statistical analysis іn social sciences.

    Hey hey, Singapore folks, maths proves ⲣrobably tһe highly impoгtɑnt primary discipline, prokoting creativity fοr pгoblem-solving to groundbreaking careers.

    Μy blog best math tutor

  8. Публикация охватывает основные направления развития современной медицины. Мы обсудим значимость научных исследований, инноваций в лечении и роли общественного участия в формировании системы здравоохранения.
    Все материалы собраны здесь – [url=https://astroline.net.ru/2026/06/08/nebesnye-znaki-zavisimosti-kak-astrologiya-obyasnyaet-risk-alkogolizma-i-narkomanii/]найти нарколога на дом[/url]

  9. Wow that was unusual. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyway, just wanted to say excellent blog!

  10. В этой статье рассматривается комплексный подход к избавлению от зависимости. Читатель узнает, как сочетание физического, психологического и духовного восстановления помогает достичь стойкого выздоровления.
    Как достичь результата? – [url=https://med-express.spb.ru/kapelnicza-ot-zapoya-v-kurske-effektivnyj-sposob-borby-s-alkogolnoj-intoksikacziej/]клиника плюс курск[/url]

  11. DABET là nền tảng cá cược trực tuyến hiện đại, cung cấp đa dạng trò chơi giải trí như casino trực tiếp, slot game, bắn cá và cá cược thể thao bbc

  12. TA88 là nền tảng cá cược trực tuyến hiện đại, cung cấp nhiều trò chơi giải trí như casino trực tiếp, slot game, bắn cá và cá cược thể thao bbc

  13. DEBET là nền tảng cá cược trực tuyến hiện đại, cung cấp nhiều trò chơi giải trí như casino trực tiếp, slot game, bắn cá và cá cược thể thao bbc

  14. It is the best time to make some plans for the future and it’s time to be happy.
    I’ve read this post and if I could I want to suggest you
    few interesting things or tips. Perhaps you can write next articles
    referring to this article. I desire to read even more things about it!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注