Mehrere Threads rufen mehrere Funktionen auf, priorisierung möglich?



  • Hi,

    ich habe mehrere Threads welche alle die gleichen Funktionen aufrufen welche auf den gleichen Datenstrukturen arbeiten. Daher löse ich das zur Zeit durch einen Mutex, so dass zu jeder Zeit nur ein Thread und eine Funktion ihre Arbeit verrichten kann (wie ein Monitor also). Jetzt ist es aber so, dass einige Funktionen die Chance erhöhen, dass die anderen Funktionen ihre Arbeit verrichten können (diese geben Ressourcen frei welche die anderen Funktionen belegen) und daher wäre es für jeden Thread vorteilhaft, wenn er Threads den Vorzug gibt die gerade in einer der Freigabe-Funktionen auf den Mutex warten. Gibt es ein Pattern oder so etwas um das zu implementieren?

    Danke.



  • ja klar, nennt sich priority-mutex.



  • hustbaer schrieb:

    ja klar, nennt sich priority-mutex.

    danke, leider finde ich mit dem Begriff nichts prägnantes. Bei den Suchtreffern geht es um Prozessprioritäten im Zusammenhang mit Mutexes. Gibt es dafür noch einen anderen Namen? Oder hast du einen Link für mich?



  • multi-threader schrieb:

    hustbaer schrieb:

    ja klar, nennt sich priority-mutex.

    danke, leider finde ich mit dem Begriff nichts prägnantes. Bei den Suchtreffern geht es um Prozessprioritäten im Zusammenhang mit Mutexes. Gibt es dafür noch einen anderen Namen?

    Hm. Vermutlich. Ich kenne aber nur den.
    Es geht einfach um die "scheduling policy", also darum wem die Mutex als nächstes Zugriff gibt, wenn mehrer Threads warten.

    "Priority Mutex" bedeutet dabei einfach, dass nicht der dran kommt der schon am längsten wartet, sondern der mit der höchsten Priorität. Was man dabei als Priorität interpretiert, also woher man diesen Wert bezieht, ist unterschiedlich. Die einfachste Variante, die aber nicht immer die beste sein muss (bzw. ganz sicher nicht immer ideal ist), ist, die Thread-Priorität gleichzeitig als Priorität für die Mutex zu verwenden.

    Oder hast du einen Link für mich?

    http://zthread.sourceforge.net/html/classZThread_1_1PriorityMutex.html
    (Bitte nicht als Empfehlung einer Library verstehen, ich halte von der zthreads nicht gerade viel. Diese Implementierung verwendet die Thread-Priority gleichzeitig als Priorität für die Mutex.)

    http://www.java2s.com/Open-Source/Java-Document/IDE-Netbeans/editor/org/netbeans/lib/editor/util/PriorityMutex.java.java-doc.htm
    (Diese Implementierung gibt genau einem Thread Priorität über alle anderen. Nicht sehr flexibel, dafür aber sehr einfach)

    ----

    Grundsätzlich kann man sich sowas relativ einfach selbst bauen, und zwar aus einer "normalen" Mutex (egal welche Scheduling Policy die verwendet) + einer Condition-Variable.



  • ABer Grundsätzlich muss gesagt werden das Du dann ein Designproblem hast.
    Normalerwiese ruft man die Funktionen auf, welche man haben möchte und reicht die Daten weiter. Das überlässt man nicht dem Programm zur Entscheidung.
    Wenn der eine Thread fertig ist soll er den anderen informieren das der nun dran ist.
    Was machst DU wenn der eine Thread eine Fehler hat produziert. Dann hängen die anderen in einem Mutex drin.



  • Also ich verwende derzeit schon eine Kombination aus Mutex + Condition-Variable und wenn ein Thread in einer Funktion blockieren würde, dann benutzt er die Condition-Variable, aber mit dieser kann ich ja nur sagen "wecke mir einen anderne Thread auf" und nicht "wecke mir einen anderen Thread auf der gerade in Funktion x, y oder z wartet".

    Danke für die Links werde ich mir gleich mal anschauen.



  • @Unix-Tom:
    Vermutlich kann man viele Dinge anders (u.U. sogar besser) lösen, ohne eine Priority-Mutex zu verwenden.

    Ich wäre mir aber nicht so sicher, dass es nicht Fälle gibt, wo eine Priority-Mutex doch sinnvoll sein kann.

    @multi-threader:
    Könntest du nicht vielleicht einfach zwei Condition-Variablen verwenden, um das zu machen, was du willst?
    Beispiel: Eine Bounded-Queue. push_back() soll blockieren, wenn die Queue bereits ihre Maximal-Länge erreicht hat - solange bis wieder Platz ist. pop_front() soll blockieren, solange die Queue leer ist.

    Natürlich kann man das mit einer einzigen Condition-Variable implementieren, die einfach für "queue status changed" steht.

    Man kann aber auch zwei Condition-Variablen verwenden. Eine steht dann für "queue not full" und die andere für "queue not empty".

    push_back() wartet dann auf wenn nötig auf "queue not full", und signalisiert nach dem Einfügen des neuen Werts "queue not empty".

    und pop_back() wartet wenn nötig auf "queue not empty", und signalisiert nach dem Rausnehmen des Werts "queue not full".

    Dadurch wird nie ein "falscher" Thread aufgeweckt. Besser noch: man muss nicht "signal_all" verwenden, da immer garantiert genau ein "passender" Thread aufgeweckt wird.


Anmelden zum Antworten