2009-02-07 9 views
2

J'ai un programme que je voudrais exécuter sur un seul processeur afin qu'il ne prenne pas trop de ressources système. Le problème est, il fait un appel dans une DLL externe qui utilise automatiquement tous les cœurs de processeur disponibles. Je n'ai pas le code source à la DLL externe. Comment puis-je limiter la DLL à l'aide d'un seul processeur?Comment limiter une DLL externe à une CPU?

EDIT: Merci pour l'aide, voici le code que je l'habitude de limiter à une CPU (Windows):

// Limit the process to only 1 thread so we don't chew up system resources 
HANDLE ProcessHandle = GetCurrentProcess(); 
DWORD ProcessAffinityMask; 
DWORD SystemAffinityMask; 
if(GetProcessAffinityMask(ProcessHandle,&ProcessAffinityMask,&SystemAffinityMask) 
    && SystemAffinityMask != 0) 
{ 
    // Limit to 1 thread by masking all but 1 bit of the system affinity mask 
    DWORD NewProcessAffinityMask = ((SystemAffinityMask-1)^SystemAffinityMask) & SystemAffinityMask; 
    SetProcessAffinityMask(ProcessHandle,NewProcessAffinityMask); 
} 

EDIT: Active l'approche de Brannon de la mise en priorité du processus fonctionne encore mieux ce que je veux , qui est de garder le processus de mâcher des ressources. Voici le code (Windows):

// Make the process low priority so we don't chew up system resources 
HANDLE ProcessHandle = GetCurrentProcess(); 
SetPriorityClass(ProcessHandle,BELOW_NORMAL_PRIORITY_CLASS); 
+0

Je pense que vous confondez votre terminologie. Ce code limite l'ensemble du processus à un seul processeur. Ce code n'a rien à voir avec les threads. – Brannon

+0

Bon point, je vais changer les termes de "thread" à "CPU". – user18476

Répondre

5

La définition de l'affinité du processeur est la mauvaise approche. Laissez le système d'exploitation gérer la planification.

Si la machine est inactive, vous devez utiliser autant de processeur que possible. Sinon, vous faites moins de travail sans raison. Si la machine est occupée, vous voulez utiliser des cycles "libres" et ne pas affecter les autres processus.

Windows a cette fonctionnalité intégrée. La solution appropriée pour cela est de définir la priorité de base du processus.

Voir http://msdn.microsoft.com/en-us/library/ms686219(VS.85).aspx pour plus de détails sur SetPriorityClass().

Si vous souhaitez tester cela sans écrire de code, utilisez le Gestionnaire des tâches pour modifier la priorité de votre processus.

0

Er ...... pourquoi? Sérieusement, pourquoi limiter une bibliothèque capable de vous donner des performances supplémentaires de cette manière? Essayez-vous d'accéder à une ressource partagée ou quelque chose? On pourrait penser qu'une bibliothèque multithread serait capable de gérer cela en toute sécurité.

À moins qu'il ya quelque chose que vous n'êtes pas mentionner, je ne vois aucune raison valable même pour essayer de limiter une bibliothèque multi-thread à un seul fil.

+0

Le programme est conçu pour fonctionner inaperçu en arrière-plan dans le cadre d'un système de construction distribué, mais il mâche beaucoup trop de ressources en utilisant tous les processeurs. – user18476

+0

+1 c'est une question très légitime. Vous devez laisser le système d'exploitation gérer la planification des threads. En outre, cela aurait été utile si vous aviez inclus cette information dans la question elle-même. Il est naturel de demander "pourquoi?", Parce que ce que vous essayez de faire est hors de l'ordinaire. – Brannon

0

Ainsi, votre programme utilise un fil, mais vous ne voulez pas la DLL externe à utiliser plus d'un fil? Vous n'avez pas beaucoup de contrôle sur ce que la DLL externe fait, mais certaines approches pourraient être:

1

Normalement, une dll vit dans le même thread/espace mémoire que le code qui l'appelle. Le fait d'appeler une DLL elle-même ne doit pas créer de threads. Si appeler la DLL semble créer plus de threads, cela signifie que la DLL elle-même crée les threads quelque part dans son code. Si vous n'avez pas de code source ou de documentation pour la DLL, vous ne pouvez pas faire grand-chose à ce sujet (et si vous voulez que la DLL fasse son travail, il n'y a pas grand chose à faire à ce sujet).

Vous pouvez essayer de jouer avec la priorité de votre demande - la mise à bas pourrait changer l'utilisation du processeur, même si elle ne change pas ce que threads sont créés. Mais il semble probable que ce que vous voulez vraiment, c'est obtenir de la documentation pour cette bête. Sans savoir comment le code fonctionne, en général, il n'y a pas grand chose à faire pour changer son fonctionnement. Aucun super génie ne peut changer cela.

0

Vous ne dites pas ce que la plate-forme est ce pour. Je vais supposer des fenêtres ici.

Créer le processus de l'enfant et l'associer à un Job Object. Vous pouvez ensuite définir l'affinité du processeur pour cet objet de travail pour inclure uniquement l'un des cœurs de processeur disponibles. Le processus enfant n'est pas en mesure de modifier le masque d'affinité pour tout ce qui n'est pas un sous-ensemble de l'affinité du processeur pour l'objet du travail. En outre, vous devez vous rappeler de ne pas définir la limite JOB_OBJECT_LIMIT_BREAKAWAY_OK ou la limite étendue JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK sur le travail, sinon le processus enfant sera en mesure de sortir du travail.

En outre, vous pouvez définir la priorité et la classe de planification pour le travail. Peut-être suffira-t-il de créer le processus fils à un niveau de priorité CPU et/ou E/S inférieur?

+0

Le .DLL de la question implique clairement Windows ou OS/2. L'équivalent sur les systèmes * nix est .SO. Comme OS/2 est à peu près un OS mort, vous pouvez supposer Windows en toute sécurité. – Randolpho