2009-06-29 8 views
2

So habe ich ein Programm, das als eine Art "Shell" für andere Programme dient. Im Kern werden eine Klasse, ein Methodenname und einige Argumente übergeben, und die Ausführung der Funktion wird so gehandhabt, dass andere Programmierer ihre Prozesse grundsätzlich so planen können, dass sie auf diesem Shell-Service ausgeführt werden. Bis auf ein Problem funktioniert alles einwandfrei. Häufig sind diese Prozesse, die zur Ausführung geplant sind, sehr CPU-lastig. Manchmal beginnen die genannten Prozesse so viel von der CPU zu verwenden, dass die Threads, die ich für das Überprüfen von Zeitplänen und das Abfeuern anderer Jobs zuständig bin, keine Chance bekommen, für eine gewisse Zeit zu laufen, was zu Zeitplanungsproblemen führt und a Mangel an ausreichender Reaktionsfähigkeit. Leider kann ich Thread.Sleep() -Aufrufe in den tatsächlichen laufenden Code nicht einfügen, da ich es nicht wirklich "besitze".Zwingen Sie einen anderen Thread zum Schlafen

Meine Frage ist also: Ist es möglich, einen willkürlichen Thread (den ich gestartet habe) zu zwingen, immer wieder einzuschlafen (yield), ohne den eigentlichen Code zu ändern, der in diesem Thread läuft? Abgesehen davon, gibt es eine Möglichkeit, Thread.Sleep() in Code zu "injizieren", den ich zur Laufzeit dynamisch ausführen möchte?

+0

Keine Antwort, aber ... wenn Sie die beteiligten Schnittstellen steuern, könnten Sie verlangen, dass ein Programm Aufruf in einem bereitgestellten Delegaten, wo Sie Co-operative Multitasking Ad-hoc (Schlaf, wenn andere Prozesse verhungern). Es hängt genau davon ab, wie viel Sie den Code nicht besitzen. –

Antwort

10

Nicht wirklich. Sie könnten versuchen, die Priorität des anderen Threads mit der Eigenschaft Priority zu ändern, aber Sie können nicht wirklich einen "Schlaf" -Aufruf injizieren.

Es gibt Thread.Suspend(), aber ich stark empfehlen, dass Sie es nicht verwenden. Sie wollen nicht wirklich wollen einen anderen Thread zu willkürlichen Zeiten zu suspendieren, da es wichtige Ressourcen halten könnte. (Deshalb ist die Methode als veraltet gekennzeichnet und enthält alle Arten von Warnungen :)

Die Reduzierung der Priorität der anderen Aufgaben und möglicherweise die Steigerung der Priorität Ihrer eigenen Aufgaben ist wahrscheinlich der beste Ansatz.

+0

Ich versuchte es mit der Priorität zu vermasseln, aber soweit ich feststellen kann, beeinflusst das, wie wahrscheinlich dieser Thread ist, um das nächste verfügbare Zeitfenster zu "gewinnen", aber es macht es nicht mehr/weniger wahrscheinlich, dass man sich selbst "ergiebt". Was das Ressourcenproblem anbelangt, nehme ich an, dass es möglich ist, aber jeder dieser Prozesse soll unabhängig sein, sofern sie jeweils in separaten AppDomains ausgeführt werden. Also sollten die Chancen von zwei Jobs, die dieselbe Ressource haben wollen, niedrig sein (aber nicht Null). – GWLlosa

+1

@GWLlosa: Timeslices sind so klein, dass das Gewinnen des nächsten verfügbaren ausreichend sein sollte, damit Ihr Planungsthread reaktionsfähig bleibt. Alles, was Sie wollen, ist, dass Sie Priorität vor den Aufgaben haben, die ausgeführt werden, und genau das wird es tun. – jerryjvl

1

Sie einen Thread mit Thread.Suspend aussetzen kann (veraltet und nicht empfohlen) oder Sie kann seine Priorität durch Ändern von Thread.Priority verringern.

0

Wenn ihre Klassen eine virtuelle SleepIfNecessary()-Methode hätten, dann glaube ich, dass Sie sie überschreiben können, indem Sie durch Reflexion eine eigene Wrapper-Klasse erstellen.

Aber sie würden wieder dafür verantwortlich sein, die Methode ab und zu während ihrer Schleifen aufzurufen.

[Bearbeiten]

Ich habe noch nie so etwas getan, aber ich sehe nicht, warum Sie nicht Ihren eigenen Methodenaufruf innerhalb eines bestehenden injizieren könnten. (Dieser Link, zum Beispiel: http://www.codeproject.com/KB/msil/reflexil.aspx)

0

Eigentlich, was Sie sagen, ist sehr ein Sicherheitsrisiko und wird daher von den meisten Plattformen nicht unterstützt werden. Es ist im Allgemeinen keine gute Richtlinie, anderen Programmen zu erlauben, Ihren Status ohne Ihre Erlaubnis zu beeinflussen.

Wenn möglich, könnten Sie wahrscheinlich das fragliche Programm auf seinen eigenen Prozess laden, den Sie in Ihrem Code erstellen, und dann können Sie die Priorität dieses Prozesses setzen oder ihn schlafen lassen, oder was Sie haben. Ich bin kein Experte in Windows-Programmierung, so dass Ihre Laufleistung variieren kann.

0

Sie sollten dies nicht tun. Threads sollten nicht schlafen(), außer sie selbst entscheiden, dass es eine gute Idee ist.

Es ist sowieso nicht relevant für Ihr Problem. Ihr Problem besteht offenbar darin, dass Verwaltungsthreads aufgrund von CPU-Mangel nicht ausgeführt werden. Um das zu beheben, reicht es aus, diesen Threads eine höhere Priorität zu geben. Am Ende jedes Zeitfensters bestimmt das Betriebssystem, welche Threads als nächstes ausgeführt werden sollen. Die Threadpriorität ist etwas dynamisch: Threads, die eine Weile nicht ausgeführt wurden, werden relativ zu Threads, die gerade ausgeführt wurden, nach oben verschoben. Die höhere Basisthread-Priorität Ihrer Verwaltungsthreads bedeutet jedoch, dass sie diesen dynamischen Boost nicht benötigen, um noch geplant zu werden.

Wenn dies immer noch nicht ausreicht, senken Sie die Priorität der Worker-Threads. Dies bedeutet, dass der Worker-Thread noch länger inaktiv sein muss, bevor er ein neues Zeitfenster erhält.

Stellen Sie abschließend sicher, dass der Thread, der neue Worker-Threads startet, mit einer sehr niedrigen Priorität ausgeführt wird. Dies bedeutet, dass keine neuen Threads erstellt werden, wenn das System die CPU-Grenzwerte erreicht. Dies implementiert einen einfachen aber robusten Drosselmechanismus.

Verwandte Themen