8
votes

Changer la priorité du fil pour rendre mon programme et votre ordinateur plus réactif

J'ai écrit une application WinForms .NET qui utilise un thread secondaire pour effectuer un certain traitement lourd, ce qui communique la progression du fil de l'interface utilisateur. Tout fonctionne correctement, le formulaire montre la progression et j'ai également créé un bouton d'annulation pour interrompre le fil de traitement. Cependant, lorsque le processus de consommation de temps consiste à utiliser l'application et que tout mon ordinateur ralentit. Il faut beaucoup de fenêtres de traînée de temps et il y a même un retard important lorsque vous essayez de taper des lettres dans le bloc-notes.

Je suppose que je dois réduire la priorité du fil de traitement et / ou augmenter la priorité de la priorité de la Fil de l'interface utilisateur. Est-ce correct? À l'heure actuelle, les deux threads sont prioritaires normaux.

est-il aussi simple que le Follwing? Ou y a-t-il quelque chose d'autre que je devrais faire? xxx

Comment dois-je modifier les priorités? Devrais-je réduire la priorité du traitement ou augmenter la priorité de l'interface utilisateur ou les deux? Et à quel cadre? Abonnement, ou le plus haut?


1 commentaires

Eric, quel type de processeur est dans votre machine de développement? À quelle fréquence le fil de travailleur communique-t-il à l'interface utilisateur?


4 Réponses :


0
votes

Vous voulez généralement laisser la priorité de votre fil principal seul et réduisez la priorité du thread de traitement au ralenti.


4 commentaires

Le réglage à Highle fera une longue course, une routine intensive de courant prendra beaucoup plus de temps, potentiellement. Mieux vaut la mettre à la Belownormal.


@Reed: Il n'y aura généralement pas de différence entre les deux du tout. La seule façon dont il y a une différence, c'est s'il y a un autre fil à la priorité oisif ou piétonnière, qui n'est pas particulièrement courante.


Il y a assez de services fixés à Belownormal. J'ai effectivement trouvé une différence notable dans mon code ...


@Reed: Cela me soupçonne-t-il de moi - dans tout le temps depuis Windows NT 3.1, je n'ai pas encore vu un service unique pour fonctionner à la priorité belwnormale. Même si une telle chose existait, cela ne ferait qu'une différence que si le service était prêt à exécuter - et quand cela se produit (normalement) signifie qu'il a été invoqué par un processus actif, auquel cas vous veulent < / Je> prendre la priorité sur votre fil de fond.



2
votes

Si vous voulez que le fil d'arrière-plan n'effectue pas la réactivité du système dans son ensemble, vous aurez besoin de réduire la priorité de sa qualité, probablement en définissant la priorité à Belownormal .

Sinon, il aura le même effet que vous voyez actuellement.

Cela étant dit, je serais hésitant à le faire dans mon propre code. Si votre programme est exécuté sur un système avec plus de cœurs de traitement, cela ne sera probablement pas un problème et une réduction de la priorité de thread (potentiellement) entraînera une prise de plus que votre algorithme.


0 commentaires

5
votes

Je ne pense pas nécessairement que votre priorité du fil est votre problème (bien que cela puisse en faire partie). Jetez un coup d'œil à cette question: Priorité de fil de travail de fond .

Ce sont probablement des boucles trop serrées dans votre fil d'arrière-plan qui gardez le temps de la CPU sur ce fil. Il existe plusieurs façons de le réparer de la brutale (dort de fil) aux plus raisonnables (mutexs et événements).

Vous pouvez également essayer de profiler le fil d'arrière-plan (directement ou dans un harnais de test) pour voir où il dépense la majorité de son temps et essayer d'isoler cela avec des événements asynchronisés ou des techniques de déchargement similaires.


2 commentaires

Si le travail est véritablement "traitement lourd", comme spécifié, alors essayant d'utiliser des mutiles et des événements, etc., va juste ralentir considérablement le traitement. Utiliser votre CPU à son maximum n'est pas une mauvaise chose - l'utiliser inutilement est le problème ...


Cela dépend de la définition de «traitement lourd». Je suis d'accord avec vous, si vous êtes déjà investi, l'ajout de commutateurs de contexte supplémentaires va simplement le faire pire. Cela a été mon expérience cependant que la segmentation de travail parfois appliquée soigneusement appliquée (utilisant des mutiles et des signaux) peut atténuer la conflit de processeur, sans avoir une incidence significative sur la vitesse, bien qu'il y aura toujours une perte.



0
votes

Normalement, vous devez définir la priorité du thread du travailleur à un niveau agréable (par exemple, l'utilisateur peut vouloir faire une autre application et même leur fil de travail devrait jouer sympa) même si Windows stimule déjà le thread "actif". (L'application que vous avez une fenêtre avec une mise au point d'entrée) un peu donc cela se sentira plus réactif. Les priorités plus élevées sont généralement nécessaires lorsque vous devez rencontrer des contraintes de temps.


8 commentaires

Également une note (pas la question principale): vous devez savoir que les fils avec des priorités différentes peuvent donner des problèmes de simultanées étranges (des choses comme: Que se passe-t-il si un thread avec une prio inférieure saisit une section critique et n'est jamais programmé à nouveau parce que Le fil de prio plus élevé prend toute la CPU)


@Ritsaert: Le planificateur Windows a la "prévention de la famine", donc même si quelque chose est défini sur une priorité faible, sa priorité sera de temps en temps "heurtée" de sorte que cela fonctionne de manière à courir et (finalement) libérer la section critique / mutex / quel que soit sa tenue.


@Jerry: Merci pour l'addition. Je sais que de nouvelles versions Windows ont cela, mais même avec cela en place, il peut tenir des serrures pendant une longue période (relativement parlant)


@Ritsaert: Ce ne sont plus que des versions Windows "plus récentes" - IIRC, il a été introduit autour du cadre Time 4.0.


@Jerry: Vous avez peut-être raison: j'ai essayé de google et il semble que cela ait été ajouté depuis la fenêtre 2000. Et je ne peux pas appeler qu'une version très récente puis-je trouver l'article suivant intéressant (voir les commentaires également) : codinghorror.com/blog/archives/000671.html


@Ritsaert: article intéressant, mais cela souligne le blâme dans la mauvaise direction. Si vous avez l'air de soigneusement, il mentionne un traitement du sommeil - et c'est la source réelle du problème. Le synchronisation de fil doit être fait avec des choses comme WaitforSingleObject, pas avec le sommeil. Si l'évolution des priorités change de comportement global, vos chances sont fausses, et ne vous procurez-vous que parce que le planificateur a beaucoup de bandes d'aide à la couvrir (mais elle ne peut utiliser que la plupart d'entre elles pour des threads prioritaires normaux / dynamiques).


@ Tritsaert: Faire un peu de regarder les commentaires sur cet article, je remarque que quelques autres personnes ont fait à peu près le même point que j'essayais.


@Jerry: Exactement, les commentaires sont particulièrement précieux. Laissons ça à ça!