CPU LIMITER - LIMITEZ L'UTILISATION DU PROCESSEUR DE CHAQUE PROCESSUS
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 2018
-
3 août 2008 à 10:35
Fraer9
Messages postés1Date d'inscriptionmardi 20 janvier 2009StatutMembreDernière intervention 3 février 2009
-
3 févr. 2009 à 15:22
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
Fraer9
Messages postés1Date d'inscriptionmardi 20 janvier 2009StatutMembreDernière intervention 3 février 2009 3 févr. 2009 à 15:22
Merci pour ce code !
Voici la meme chose en c#, c'est une variante plus simple (qu'un seul timer) a utiliser avec l'api JobObjectWrapper (voir http://www.codeplex.com/JobObjectWrapper) pour la limitation d'un ensemble de processus (1 limite pour n processus).
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Timers;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Process[] par = Process.GetProcessesByName("ProcessLauncher");
CPULimiter cpuLimiter = new CPULimiter(10);
cpuLimiter.addProcessToWatchList(par[0]);
// Wait a little
System.Threading.Thread.Sleep(5000);
cpuLimiter.addProcessToWatchList(par[1]);
Console.ReadLine();
}
}
class ProcessWatcher
{
private readonly Process _watchedProcess;
private readonly PerformanceCounter _performanceCounter;
private bool _isSuspended;
public ProcessWatcher(Process processToWatch)
{
this._watchedProcess = processToWatch;
this._performanceCounter = new PerformanceCounter(
"Process",
"% Processor Time",
processToWatch.ProcessName);
// Init the perf counter
this._performanceCounter.NextValue();
this._isSuspended = false;
}
public Process watchedProcess
{
get { return this._watchedProcess; }
}
public PerformanceCounter performanceCounter
{
get { return this._performanceCounter; }
}
public bool isSuspended
{
get { return this._isSuspended; }
set { this._isSuspended = value; }
}
}
public CPULimiter(int maxCpuUsagePercentageBase100)
{
// Initialize the list
this.watchList = new List();
// Convert to processor count based percentage
this.maxCpuUsagePercetage = maxCpuUsagePercentageBase100 * Environment.ProcessorCount;
// Create the watching timer
this.watchingTimer = new Timer();
// Hook up the Elapsed event for the timer.
this.watchingTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the timer refresh rate
this.watchingTimer.Interval = REFRESH_RATE_BASE_MS;
}
public void addProcessToWatchList(Process processToWatch)
{
// Stop the timer...
this.watchingTimer.Enabled = false;
// Add this watcher to the watch list
this.watchList.Add(new ProcessWatcher(processToWatch));
// Restart the timer
this.watchingTimer.Enabled = true;
}
// Executed by a timer every REFRESH_RATE_BASE_MS
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
// Manually stop the timer...
this.watchingTimer.Enabled = false;
// Save the last exceeding cpu usage
float lastExceedingCpuUsage = 0;
bool cpuUsageLimitExceeded = false;
for (int i = this.watchList.Count - 1; i >= 0; i--)
{
ProcessWatcher processWatcher = this.watchList[i];
// Check if the process has exited
if (processWatcher.watchedProcess.HasExited)
{
// Remove this process watcher from the watch list
this.watchList.RemoveAt(i);
}
else
{
// If the process is suspended resume it
if (processWatcher.isSuspended)
{
// Re init the perf counter since the process was suspended
processWatcher.performanceCounter.NextValue();
if (NtResumeProcess(processWatcher.watchedProcess.Handle) == 0)
{
processWatcher.isSuspended = false;
}
else
{
// Something bad happended so remove this watcher
this.watchList.RemoveAt(i);
}
}
else
{
lastExceedingCpuUsage = processWatcher.performanceCounter.NextValue();
if (lastExceedingCpuUsage > this.maxCpuUsagePercetage)
{
//Console.WriteLine("Process reached the limit Process:{0} CPU% {1}", processWatcher.performanceCounter.InstanceName, lastExceedingCpuUsage);
cpuUsageLimitExceeded = true;
break;
}
}
}
}
int nextInterval = REFRESH_RATE_BASE_MS;
// If cpu usage has been reached
if (cpuUsageLimitExceeded)
{
for (int i = this.watchList.Count - 1; i >= 0; i--)
{
ProcessWatcher processWatcher = this.watchList[i];
// Check if the process has exited
if (processWatcher.watchedProcess.HasExited)
{
// Remove this process watcher from the watch list
this.watchList.RemoveAt(i);
}
else
{
// Since some process watchers can already be suspended we need to check the state
if (!processWatcher.isSuspended)
{
// Suspend the process
if (NtSuspendProcess(processWatcher.watchedProcess.Handle) == 0)
{
processWatcher.isSuspended = true;
}
else
{
// Something bad happended so remove this watcher
this.watchList.RemoveAt(i);
}
}
}
}
// Compute the time to wait in order to reach the given percentage
// formula : TimeToWait = BASE * ((previous_percentage / wanted_percentage) - 1)
nextInterval = Convert.ToInt32(REFRESH_RATE_BASE_MS * ((lastExceedingCpuUsage / this.maxCpuUsagePercetage) - 1));
if (nextInterval < 20) {
nextInterval = 20;
}
}
// Change the next start
this.watchingTimer.Interval = nextInterval;
this.watchingTimer.Enabled = true;
}
}
}
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 16 sept. 2008 à 13:01
zavier666
Messages postés266Date d'inscriptionmardi 7 septembre 2004StatutMembreDernière intervention30 avril 20091 12 sept. 2008 à 21:33
Si il y avait une élection du code de l'année, je crois que l'on tiendrait le gagnant et de loin. Il faut absolument que tu compiles et que tu distribues. J'ai longtemps cherché et même pensé que cela n'étais pas possible!
cs_adamama
Messages postés2Date d'inscriptionmercredi 5 mars 2008StatutMembreDernière intervention 9 août 2008 9 août 2008 à 01:11
good job
;)
killer123456789
Messages postés11Date d'inscriptionlundi 4 avril 2005StatutMembreDernière intervention 3 août 2008 3 août 2008 à 16:28
Félicitation! Très bon programme. Justement je cherchais un programme de ce genre pour laisser rouler un programme sur mon ordi sans que celui-ci utilise 100% du CPU mais j'avais pas trouver de programme semblable au tien.
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 3 août 2008 à 12:40
Ah content que ça puisse intéresser quelqu'un.
Alors oui, ça pourrait faire ce que tu veux : à savoir limiter ton appli gourmande à 50% maximum d'utilisation CPU. Par contre ça influe forcément sur le rendement de cette application : à 50%, elle sera 2 fois moins productive.
Mais ton problème ne pourrait-il pas être (en partie) réglé en définissant ton processus à une priorité faible, comme ça ça ne gênerait pas l'exécution d'autres taches ? Après, si tu veux vraiment que son exécution soit transparente tu peux utiliser en complément mon programme, pour être sur qu'il y'aura toujours du temps processeur de libre pour n'importe quelle autre appli... A voir.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 3 août 2008 à 10:35
Salut MadM@tt,
Tu viens de toucher une de mes cordes sensibles... :)
Au bureau, j'utilise justement une application qui prend 100% du CPU, ce qui occasionne des problèmes lorsqu'on veut utiliser d'autres applis comme Excel ou Outlook... Je dois donc utiliser 2 ordis pour être efficace.
Est-ce à dire que ton programme pourrait limiter mon application gourmande à utiliser seulement 50% du CPU, disons, et laisser un peu de place pour les autres applis ? Et est-ce que ça ne nuira pas au rendement de cette application ?
3 févr. 2009 à 15:22
Voici la meme chose en c#, c'est une variante plus simple (qu'un seul timer) a utiliser avec l'api JobObjectWrapper (voir http://www.codeplex.com/JobObjectWrapper) pour la limitation d'un ensemble de processus (1 limite pour n processus).
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Timers;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Process[] par = Process.GetProcessesByName("ProcessLauncher");
CPULimiter cpuLimiter = new CPULimiter(10);
cpuLimiter.addProcessToWatchList(par[0]);
// Wait a little
System.Threading.Thread.Sleep(5000);
cpuLimiter.addProcessToWatchList(par[1]);
Console.ReadLine();
}
}
class ProcessWatcher
{
private readonly Process _watchedProcess;
private readonly PerformanceCounter _performanceCounter;
private bool _isSuspended;
public ProcessWatcher(Process processToWatch)
{
this._watchedProcess = processToWatch;
this._performanceCounter = new PerformanceCounter(
"Process",
"% Processor Time",
processToWatch.ProcessName);
// Init the perf counter
this._performanceCounter.NextValue();
this._isSuspended = false;
}
public Process watchedProcess
{
get { return this._watchedProcess; }
}
public PerformanceCounter performanceCounter
{
get { return this._performanceCounter; }
}
public bool isSuspended
{
get { return this._isSuspended; }
set { this._isSuspended = value; }
}
}
class CPULimiter
{
[DllImport("ntdll.dll", EntryPoint = "NtResumeProcess", SetLastError = true)]
private static extern uint NtResumeProcess(IntPtr processHandle);
[DllImport("ntdll.dll", EntryPoint = "NtSuspendProcess", SetLastError = true)]
private static extern uint NtSuspendProcess(IntPtr processHandle);
// see if 1sec based rate in ms is not too often
public const int REFRESH_RATE_BASE_MS = 100;
private readonly List watchList;
private readonly float maxCpuUsagePercetage;
private readonly Timer watchingTimer;
public CPULimiter(int maxCpuUsagePercentageBase100)
{
// Initialize the list
this.watchList = new List();
// Convert to processor count based percentage
this.maxCpuUsagePercetage = maxCpuUsagePercentageBase100 * Environment.ProcessorCount;
// Create the watching timer
this.watchingTimer = new Timer();
// Hook up the Elapsed event for the timer.
this.watchingTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the timer refresh rate
this.watchingTimer.Interval = REFRESH_RATE_BASE_MS;
}
public void addProcessToWatchList(Process processToWatch)
{
// Stop the timer...
this.watchingTimer.Enabled = false;
// Add this watcher to the watch list
this.watchList.Add(new ProcessWatcher(processToWatch));
// Restart the timer
this.watchingTimer.Enabled = true;
}
// Executed by a timer every REFRESH_RATE_BASE_MS
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
// Manually stop the timer...
this.watchingTimer.Enabled = false;
// Save the last exceeding cpu usage
float lastExceedingCpuUsage = 0;
bool cpuUsageLimitExceeded = false;
for (int i = this.watchList.Count - 1; i >= 0; i--)
{
ProcessWatcher processWatcher = this.watchList[i];
// Check if the process has exited
if (processWatcher.watchedProcess.HasExited)
{
// Remove this process watcher from the watch list
this.watchList.RemoveAt(i);
}
else
{
// If the process is suspended resume it
if (processWatcher.isSuspended)
{
// Re init the perf counter since the process was suspended
processWatcher.performanceCounter.NextValue();
if (NtResumeProcess(processWatcher.watchedProcess.Handle) == 0)
{
processWatcher.isSuspended = false;
}
else
{
// Something bad happended so remove this watcher
this.watchList.RemoveAt(i);
}
}
else
{
lastExceedingCpuUsage = processWatcher.performanceCounter.NextValue();
if (lastExceedingCpuUsage > this.maxCpuUsagePercetage)
{
//Console.WriteLine("Process reached the limit Process:{0} CPU% {1}", processWatcher.performanceCounter.InstanceName, lastExceedingCpuUsage);
cpuUsageLimitExceeded = true;
break;
}
}
}
}
int nextInterval = REFRESH_RATE_BASE_MS;
// If cpu usage has been reached
if (cpuUsageLimitExceeded)
{
for (int i = this.watchList.Count - 1; i >= 0; i--)
{
ProcessWatcher processWatcher = this.watchList[i];
// Check if the process has exited
if (processWatcher.watchedProcess.HasExited)
{
// Remove this process watcher from the watch list
this.watchList.RemoveAt(i);
}
else
{
// Since some process watchers can already be suspended we need to check the state
if (!processWatcher.isSuspended)
{
// Suspend the process
if (NtSuspendProcess(processWatcher.watchedProcess.Handle) == 0)
{
processWatcher.isSuspended = true;
}
else
{
// Something bad happended so remove this watcher
this.watchList.RemoveAt(i);
}
}
}
}
// Compute the time to wait in order to reach the given percentage
// formula : TimeToWait = BASE * ((previous_percentage / wanted_percentage) - 1)
nextInterval = Convert.ToInt32(REFRESH_RATE_BASE_MS * ((lastExceedingCpuUsage / this.maxCpuUsagePercetage) - 1));
if (nextInterval < 20) {
nextInterval = 20;
}
}
// Change the next start
this.watchingTimer.Interval = nextInterval;
this.watchingTimer.Enabled = true;
}
}
}
16 sept. 2008 à 13:01
http://www.vbfrance.com/codes/WIN-OPTIONS-AVANCEES-SUR-FENETRES-PROCESSUS-WINDOWS-CPU_47970.aspx
13 sept. 2008 à 20:59
Concernant la version compilée avec un installeur, c'est déjà fait :
http://www.mnapoli.fr/programmes/cpulimiter.php
12 sept. 2008 à 21:33
9 août 2008 à 01:11
;)
3 août 2008 à 16:28
3 août 2008 à 12:40
Alors oui, ça pourrait faire ce que tu veux : à savoir limiter ton appli gourmande à 50% maximum d'utilisation CPU. Par contre ça influe forcément sur le rendement de cette application : à 50%, elle sera 2 fois moins productive.
Mais ton problème ne pourrait-il pas être (en partie) réglé en définissant ton processus à une priorité faible, comme ça ça ne gênerait pas l'exécution d'autres taches ? Après, si tu veux vraiment que son exécution soit transparente tu peux utiliser en complément mon programme, pour être sur qu'il y'aura toujours du temps processeur de libre pour n'importe quelle autre appli... A voir.
3 août 2008 à 10:35
Tu viens de toucher une de mes cordes sensibles... :)
Au bureau, j'utilise justement une application qui prend 100% du CPU, ce qui occasionne des problèmes lorsqu'on veut utiliser d'autres applis comme Excel ou Outlook... Je dois donc utiliser 2 ordis pour être efficace.
Est-ce à dire que ton programme pourrait limiter mon application gourmande à utiliser seulement 50% du CPU, disons, et laisser un peu de place pour les autres applis ? Et est-ce que ça ne nuira pas au rendement de cette application ?
Intéressant, en tout cas, comme projet.