2

Ich habe 3 Klassen von Aufgabe (I, D, U), die in einer Warteschlange kommen, Aufgaben der gleichen Klasse müssen in der Reihenfolge verarbeitet werden. Ich möchte, dass Tasks so gleichzeitig wie möglich ausgeführt werden. jedoch gibt es einige Einschränkungen:Entwurfsmuster für die gleichzeitige Ausführung von Aufgaben mit Einschränkungen

  • U und D nicht gleichzeitig
  • U laufen und kann nicht gleichzeitig
  • I (n) erfordert U (n) abgeschlossen laufen

Q hat: Welches Designmuster würde zu dieser Problemklasse passen?

Ich habe zwei Ansätze, die ich überlege:

Ansatz 1: Verwendung 1 Thread pro Aufgabe, jedes mit seiner eigenen Warteschlange. Jeder Thread hat eine synchronisierte Startphase, in der er die Startbedingungen überprüft und dann eine synchronisierte Stopp-Phase ausführt. Es ist leicht zu sehen, dass dies gute Nebenläufigkeit bietet, aber ich bin unsicher, ob es meine Einschränkungen korrekt implementiert und nicht blockiert.

D_Thread { ... 
while (task = D_Queue.take()) { 
    synchronized (State) { // start phase 
    waitForU(); 
    State.setRunning(D, true); 
    } 
    run(task); // run phase 
    synchronized (State) { // stop phase 
    State.setRunning(D, false) 
    } 
} 
} 

Ansatz 2: Alternativ kann ein einzelner Dispatch Thread verwaltet Ausführungszustand und Zeitplan Aufgaben in einem Threadpool, warten, wenn notwendig, zur Zeit geplanter Aufgaben abzuschließen.

+0

Könnten Sie mehr über dritte Einschränkung näher erläutern? Kommen I und U paarweise und jeder I benötigt sein gepaartes U, oder es gibt keine solchen Paare, aber nur die Anzahl der vervollständigten I's kann nicht größer sein als die Anzahl der vervollständigten U's. Oder etwas anderes? – Dialecticus

+0

2) Wie hoch sind die Zeitkosten für jede Aufgabenklasse? Nehmen sie ungefähr die gleiche Zeit in Anspruch? – Dialecticus

+0

Ein bisschen von beidem. U (n) ist eine Art Cache-Flush, es impliziert U (n-1) U (n-2) ... und so weiter; So ist es möglich mehrere gleichzeitig zu bearbeiten. Jeder Operation ist eine Position zugeordnet; also schafft D (k) tatsächlich eine Anforderung für U (k). Sie waren als Beispiele gemeint; Ich bitte die Leute nicht, dieses Problem vollständig zu lösen. empfehle einfach einige Designmuster. – Justin

Antwort

1

Das Framework Objective-C Foundation enthält die Klassen NSOperationQueue und NSOperation, die einige dieser Anforderungen erfüllen. NSOperationQueue steht für eine Warteschlange von NSOperation s. Die Warteschlange führt eine konfigurierbare maximale Anzahl von Operationen gleichzeitig aus. Operationen haben eine Priorität und eine Reihe von Abhängigkeiten; Alle Operationen, von denen eine Operation abhängt, müssen abgeschlossen sein, bevor die Warteschlange mit der Ausführung der Operation beginnt. Die Vorgänge werden in einem Thread-Thread mit dynamischer Größe ausgeführt. Sie benötigen eine etwas intelligentere Version von NSOperationQueue, die die von Ihnen geäußerten Einschränkungen anwendet, aber NSOperationQueue und das Unternehmen geben ein Beispiel dafür, wie grob Ihr Problem in einem Produktionsframework gelöst wurde, das Ihrer zweiten vorgeschlagenen Lösung eines Dispatchs ähnelt Thread, die Aufgaben in einem Thread-Pool ausführen.

+0

Es sieht so aus, als ob NSOperationQueue einen gerichteten azyklischen Abhängigkeitengraphen und einen beschränkten Thread-Pool verwendet, um alles zu planen, für das kein anderes Ergebnis aussteht. – Justin

+0

Ich konnte keine Möglichkeit sehen, meine Einschränkungen in Bezug auf Vorwärtsabhängigkeiten auszudrücken. – Justin

+0

Ich nehme es, das löst das Problem nicht, aber es ist, was ich gefragt habe. – Justin

0

Eigentlich dreht sich diese einfacher zu sein, als es schien: ein Mutex vor allem ist alles, was benötigt wird:

IThread(int k) { 
synchronized (u_mutex) { 
    if (previousUSet.contains(k))) U(k); 
} 
I(k); 
} 

DThread(int k) { 
synchronized (u_mutex) { 
    D(k); 
    previousUSet.add(k); 
} 
} 
Verwandte Themen