4D v16.3

Preemptive 4D Prozesse

Home

 
4D v16.3
Preemptive 4D Prozesse

Preemptive 4D Prozesse  


 

 

4D Developer Edition 64-bit für OS X und ab 4D v16 R2 für Windows bietet ein leistungsstarkes neues Feature zum Schreiben und Verwenden von preemptive 4D Code. Damit können Ihre kompilierten 4D Anwendungen die Vorteile von multi-core Computern nutzen, um die Ausführung zu beschleunigen und mehr angemeldete Benutzer zu unterstützen.

Beim preemptive Modus (unterbrechend) ist der Prozess einer CPU zugeordnet. Die Prozessverwaltung wird dann an das System delegiert, das jede CPU einem multi-core Rechner einzeln zuweisen kann.

Beim kooperativen Modus (nicht-unterbrechend - in 4D bis v15 R4 der einzige verfügbare Modus) werden alle Prozesse vom übergeordneten Applikation Thread verwaltet und nutzen dieselbe CPU gemeinsam, und das auch auf einem multi-core Rechner. 

Durch den preemptive Modus wird die globale Performance der Applikation erhöht, insbesondere auf multi-core Rechnern, da mehrfache Prozesse (Threads) real simultan laufen können. Der jeweilige Gewinn hängt jedoch von den ausgeführten Operationen ab.

Außerdem gelten für Methoden, die preemptiv nutzbar sein sollen, spezifische Einschränkungen. Denn im preemptive Modus ist jeder Thread von den anderen unabhängig und wird nicht direkt von der Applikation verwaltet. Zusätzlich ist die preemptive Ausführung nur in ganz bestimmten Kontexten verfügbar.

Der preemptive Modus ist nur in 64-bit Versionen verfügbar. Derzeit werden folgende Ausführungskontexte unterstützt:

Preemptive Ausführung
4D ServerX
4D Remote-
4D EinzelplatzX
Kompilierter ModusX
Interpretierter Modus-

Unterstützt der Ausführungskontext den preemptive Modus und ist die Methode "thread-safe", wird ein neuer 4D Prozess, gestartet über die Befehle New process oder CALL WORKER oder über den Menübefehl "Methode ausführen", in einem preemptive Thread ausgeführt.

Rufen Sie dagegen New process oder CALL WORKER in einem Ausführungskontext auf, der nicht unterstützt wird (z.B. auf einem Rechner mit remote 4D), ist der Prozess immer kooperativ.

Hinweis: Von einem remote 4D aus kann ein Prozess im preemptive Modus laufen, wenn eine Serverprozedur auf dem Server per Programmierung aufgerufen wird, z.B. mit dem Befehl Execute on server.

4D Code kann nur unter ganz bestimmten Bedingungen in einem preemptive Thread laufen. Jeder Teil des ausgeführten Code (Befehle, Methoden, Variablen) muss mit einer preemptive Ausführung kompatibel sein. Elemente, die in preemptive Threads laufen können, werden thread-safe genannt. Elemente, die nicht in preemptive Threads laufen können, werden thread-unsafe genannt.

Hinweis: Da ein Thread unabhängig von der ihn startenden übergeordneten Prozessmethode verwaltet wird, darf die gesamte Aufrufkette keinen thread-unsafe Code enthalten, da dann keine preemptive Ausführung möglich ist. Weitere Informationen dazu finden Sie im Abschnitt Wann startet ein Prozess preemptive?

Die Eigenschaft "thread-safe" für jedes Element hängt vom Element selbst ab:

  • 4D Befehle: Thread-Sicherheit ist eine interne Eigenschaft. Im Handbuch 4D Programmiersprache werden thread-safe Befehle mit dem Icon gekennzeichnet. Ein großer Teil der 4D Befehle kann im preemptive Modus laufen.
  • Projektmethoden: Die Bedingungen für thread-safe werden im Abschnitt Eine thread-safe Methode schreiben beschrieben.

Im allgemeinen kann Code, der in preemptive Threads laufen soll, keine Teile mit externen Interaktionen aufrufen, wie Plug-In Code oder Interprozessvariablen. Zugriff auf Daten ist dagegen erlaubt, da der 4D Daten-Server die preemptive Ausführung unterstützt.

4D führt standardmäßig alle Projektmethoden im kooperativen Modus aus. Um die Vorteile des preemptive Modus zu nutzen, müssen Sie zuerst alle Methoden, die nach Möglichkeit im preemptive Modus starten sollen, explizit deklarieren. Das sind die als preemptiv nutzbar geltenden Methoden. Der Compiler prüft, ob solche Methoden tatsächlich thread-safe sind. Weitere Informationen dazu finden Sie im Abschnitt Eine thread-safe Methode schreiben. Bei Bedarf können Sie den preemptive Modus für einige Methoden auch nicht erlauben.

Beachten Sie, dass eine als preemptiv nutzbar deklarierte Methode lediglich für die preemptive Ausführung wählbar ist, aber nicht garantiert, dass sie in Echtzeit tatsächlich im preemptive Modus ausgeführt wird. Ob ein Prozess im preemptive Modus gestartet wird, richtet sich nach der Bewertung, die 4D für die Eigenschaften aller Methoden in der Aufrufkette des Prozesses durchführt. Weitere Informationen dazu finden Sie im Abschnitt Wann startet ein Prozess preemptive?.

Im Dialogfenster Methode Eigenschaften gibt es die neue Option Ausführungsmodus, um eine Methode für den preemptive Modus wählbar zu deklarieren:

 

Es gibt folgende Optionen:

  • Als preemptive Prozess starten: Mit dieser Option deklarieren Sie, dass die Methode in einem preemptive Prozess laufen kann, d.h. sie soll wenn möglich, im preemptive Modus laufen.
    Der 4D Compiler überprüft, ob die Methode aktuell preemptiv nutzbar ist, andernfalls gibt er Fehler zurück -- das ist der Fall, wenn Befehle oder Methoden direkt oder indirekt aufgerufen werden, die nicht im preemptive Modus laufen können (die gesamte Aufrufkette wird durchlaufen, aber Fehler werden auf der ersten Unterebene protokolliert). Sie können dann die Methode bearbeiten, damit sie thread-safe wird, oder eine andere Option wählen.
    Ist die preemptive Nutzbarkeit der Methode bestätigt, wird sie intern als "thread-safe" markiert und im preemptive Modus ausgeführt, sobald alle erforderlichen Bedingungen zutreffen. Diese Eigenschaft definiert die Wahlmöglichkeit des preemptive Modus, garantiert aber nicht, dass die Methode tatsächlich in diesem Modus läuft, da dafür ein spezifischer Kontext erforderlich ist (siehe ).
  • Nicht als preemptive Prozess starten: Mit dieser Option deklarieren Sie, dass die Methode nie im preemptive Modus laufen soll, d.h. sie muss immer im kooperativen Modus laufen, wie in bisherigen 4D Versionen.
    Der 4D Compiler überprüft nicht, ob die Methode im preemptive Modus laufen kann; sie wird automatisch intern als "thread-unsafe" eingestuft (selbst wenn sie theoretisch preemptiv nutzbar wäre). Beim Aufrufen in Echtzeit kontaminiert diese Methode alle anderen Methoden im gleichen Thread und erzwingt so die Ausführung im kooperativen Modus (selbst wenn andere Methoden "thread-safe" sind).
  • Automatisch wählen: Mit dieser Option deklarieren Sie, dass Sie die preemptive Nutzbarkeit für die Methode nicht verwalten wollen.
    Der 4D Compiler bewertet die preemptive Nutzbarkeit der Methode und stuft sie intern als "thread-safe" oder "thread-unsafe" ein. Es wird kein Fehler zur preemptive Ausführung gemeldet. Wird die Methode als "thread-safe" gewertet und in einem preemptive Kontext aufgerufen, verhindert das in Echtzeit nicht die preemptive Thread-Ausführung. Wird sie umgekehrt als "thread-unsafe" gewertet, verhindert das bei Aufrufen in Echtzeit jede preemptive Thread-Ausführung.
    Beachten Sie, dass mit dieser Option eine Methode, unabhängig von ihrer internen Bewertung der Thread-Sicherheit, immer im kooperativen Modus ausgeführt wird, wenn sie von 4D direkt als erste übergeordnete Methode aufgerufen wird (z.B. über die Funktion New process). Ist sie intern als thread-safe eingestuft, wird sie nur berücksichtigt, wenn sie von anderen Methoden innerhalb einer Aufrufkette aufgerufen wird.
 

Hinweis: Eine Komponentmethode, deklariert als "Gemeinsam von Komponenten und Host benutzt", muss auch als preemptiv nutzbar deklariert werden, damit sie über die Host Datenbank in einem preemptive Thread laufen kann.

Beim Export des Methoden-Code, z.B. mit METHOD GET CODE, wird die Eigenschaft "preemptiv" im Attribut des Parameters Befehl mit dem Wert "auto", "safe" oder "unsafe" exportiert. Auch die Befehle METHOD GET ATTRIBUTES und METHOD SET ATTRIBUTES erhalten oder setzen das Attribut "preemptiv" mit dem Wert "auto", "safe" oder "unsafe".

Nachfolgende Tabelle zeigt die Auswirkung der verschiedenen Optionen für preemptive Modus:

OptionWert der Eigenschaft preemptiv (interpretiert)Compiler AktionInternes Tag (kompiliert)Ausführungsmodus bei thread-safe Kette
Kann in preemptive Prozessen laufenFähigPrüft die Fähigkeit und gibt Fehler zurück, wenn unfähigthread-safePreemptiv
Kann nicht in preemptive Prozessen laufenUnfähigKeine Bewertungthread-unsafeKooperativ
Keine DifferenzierungautoBewertung, aber keine Fehlermeldungthread-safe oder thread-unsafeWenn thread-safe: preemptiv; wenn thread-unsafe: kooperativ; bei direktem Aufruf: kooperativ

Zur Erinnerung: Die preemptive Ausführung ist nur im kompilierten Modus möglich.

Beim Starten eines Prozesses, der entweder über New process oder CALL WORKER erstellt wurde, liest 4D im kompilierten Modus die preemptive Eigenschaft der Prozessmethode (auch Eltern Methode genannt) und führt den Prozess je nach definierter Eigenschaft im preemptive oder kooperativen Modus aus:

  • Ist die Prozessmethode thread-safe (während der Kompilierung bestätigt), wird der Prozess in einem preemptive Thread ausgeführt
  • Ist die Prozessmethode thread-unsafe, läuft der Prozess in einem kooperativen Thread.
  • Lautet die preemptive Eigenschaft der Prozessmethode "automatisch wählen", läuft der Prozess zur Wahrung der Kompatibilität in einem kooperativen Thread (selbst wenn die Methode tatsächlich preemptiv nutzbar ist). Beachten Sie jedoch, dass diese Kompatibilität nur angewandt wird, wenn die Methode als Prozessmethode verwendet wird: Eine Methode im Ausführungsmodus "automatisch wählen", die aber vom Compiler intern als "thread-safe" eingestuft wird, lässt sich von einer anderen Methode als preemptiv aufrufen (siehe unten).

Die aktuelle Eigenschaft thread-safe richtet sich nach der Aufruffolge. Ruft eine als preemptiv nutzbar deklarierte Methode auf einer ihrer Unterebenen eine thread-unsafe Methode auf, wird ein Kompilierungsfehler zurückgegeben: Ist eine einzelne Methode innerhalb der gesamten Aufruffolge thread-unsafe, kontaminiert sie alle anderen Methoden und der Compiler verweigert die preemptive Ausführung. Ein preemptive Thread lässt sich nur erstellen, wenn die gesamte Aufruffolge thread-safe ist und die Prozessmethode als "Als preemptive Prozess starten" deklariert ist.
Andererseits lässt sich die gleiche thread-safe Methode in einer Aufruffolge in einem preemptive Thread ausführen, in einer anderen Aufruffolge dagegen im kooperativen Thread.

Hier sehen Sie ein paar Beispiele für Projektmethoden:

  //Projektmethode MyDialog
  //enthält Aufrufe der Oberfläche: ist intern thread unsafe
 $win:=Open form window("tools";Palette form window)
 DIALOG("tools")

  //Projektmethode MyComp
  //enthält einfache Berechnung: ist intern thread safe
 C_LONGINT($0;$1)
 $0:=$1*2

  //Projektmethode CallDial
 C_TEXT($vName)
 MyDialog

  //Projektmethode CallComp
 C_LONGINT($vAge)
 MyCom($vAge)

Nachfolgende Übersicht zeigt die verschiedenen Situationen:

Deklaration und AufruffolgeKompilierungResultierende Thread SicherheitKommentarAusführung
OKMethode A ist die übergeordnete Methode, deklariert als preemptive nutzbar; da Methode B intern thread-safe ist, ist Methode A thread-safe und der Prozess preemptivPreemptive
FehlerMethode C ist die übergeordnete Methode, deklariert als preemptive nutzbar; da aber Methode E intern thread-unsafe ist, kontaminiert sie die Aufruffolge und die Kompilierung schlägt fehl wegen Konflikt mit Methode C.Die Lösung ist entweder, Methode E thread-safe zu machen (ausgehend, dass Methode D thread-safe ist), so dass die Ausführung preemptive läuft oder im kooperativen Modus zu arbeiten (die Deklaration der Methode C verändern).
OKDa Methode F als preemptive nicht nutzbar deklariert ist, ist die Kompilierung intern thread-unsafe, die Ausführung läuft immer kooperativ, egal welchen Status Methode G hat.Kooperativ
OKDa Methode H die übergeordnete Methode ist (Eigenschaft "Automatisch wählen"), ist der Prozess kooperativ. Die Kompilierung ist erfolgreich, selbst wenn Methode I als preemptive nutzbar deklariert istKooperativ
OKMethode J ist die übergeordnete Methode (Eigenschaft "Nicht-zugeordnet"), der Prozess ist dann kooperativ, selbst wenn die gesamte Aufruffolge thread-safe istKooperativ

4D ermöglicht, den Ausführungsmodus für Prozesse im kompilierten Modus herauszufinden:

  • Über den Befehl PROCESS PROPERTIES finden Sie heraus, ob ein Prozess im preemptive oder kooperativen Modus läuft.
  • Das Runtime Explorer und das 4D Server Verwaltungsfenster zeigt für preemptive Prozesse und Worker Prozesse spezifische Icons an:
    ProzesstypIcon
    Preemptive Serverprozedur
    Preemptive Worker Prozess
    Cooperative Worker Prozess

Für eine thread-safe Methode gelten folgende Regeln:

  • Sie muss die Eigenschaft "Als preemptive Prozess starten" oder "Automatisch wählen" haben
  • Sie ruft keinen 4D Befehl auf, der thread-unsafe ist
  • Sie ruft keine andere Projektmethode auf, die thread-unsafe ist
  • Sie ruft kein Plug-In auf
  • Sie ruft keine Code-Sequenzen mit begin sql/end sql auf
  • Sie verwendet keine Interprozessvariablen *
  • Sie verwendet keine Objekte der Oberfläche ** (bis auf wenige Ausnahmen, siehe unten).

Für eine Methode mit der Eigenschaft "Gemeinsam von Komponenten und Host benutzt" muss auch die Eigenschaft "Als preemptive Prozess starten" markiert sein.

(*) Eine neue Art mit Namen Worker Prozess ermöglicht, Daten zwischen allen Prozessen auszutauschen, inkl. preemptive Prozesse. Weitere Informationen dazu finden Sie im Abschnitt Nachrichten zwischen Prozessen austauschen.
(**) Der neue Befehl CALL FORM bietet eine elegante Lösung, um Objekte der Oberfläche aus einem preemptive Prozess aufzurufen.

Methoden mit der Eigenschaft "Als preemptive Prozess starten" werden von 4D auch beim Kompilieren überprüft. Findet der Compiler etwas, das thread-safe verhindert, wird ein Kompilierungsfehler ausgegeben:

Ist die Symbol Datei aktiviert, zeigt sie für jede Methode den Status der Thread-Sicherheit:

Aufrufen von Objekten der Benutzeroberfläche, z.B. Formulare oder Öffnen des Debuggers sind externe Zugriffe und deshalb in preemptive Threads nicht erlaubt.

Die Benutzeroberfläche ist von einem preemptive Thread aus nur in folgenden Fällen verwendbar:

  • Standard Fehlerdialog: Er erscheint im Prozess Benutzermodus (4D Einzelplatz) oder Server Benutzeroberflächenprozess (4D Server). Die Schaltfläche Schritt ist deaktiviert.
  • Standard Ablaufbalken
  • Dialogfenster ALERT, REQUEST und CONFIRM. Er erscheint im Prozess Benutzermodus (4D Einzelplatz) oder Server Benutzeroberflächenprozess (4D Server).
    Beachten Sie, dass die Dialogfenster nicht erscheinen, wenn 4D Server als Service unter Windows gestartet wurde und keine Benutzeraktion erlaubt ist. 

Eine beträchtliche Anzahl von 4D Befehlen sind thread-safe. Bei den Befehlen im Handbuch 4D Programmiersprache zeigt das Icon im Bereich Eigenschaften rechts oben an, dass dieser Befehl thread-safe ist. Klicken Sie auf das Icon, erscheint die Liste der thread-safe Befehle.

Die Funktion Command name kann die Eigenschaft Thread-Sicherheit für jeden Befehl zurückgeben (siehe unten).

Trigger  

Bei einer Methode mit einem Befehl, der Trigger aufrufen kann, bewertet der 4D Compiler zum Überprüfen der Thread-Sicherheit der Methode die Thread-Sicherheit des Trigger:

 SAVE RECORD([Table_1]//Trigger auf Table_1, wenn vorhanden, muss thread-safe sein

Hier die Liste der Befehle, die beim Kompilieren auf Thread-Sicherheit des Trigger geprüft werden:

  • SAVE RECORD
  • SAVE RELATED ONE
  • DELETE RECORD
  • DELETE SELECTION
  • ARRAY TO SELECTION
  • JSON TO SELECTION
  • APPLY TO SELECTION
  • IMPORT DATA
  • IMPORT DIF
  • IMPORT ODBC
  • IMPORT SYLK
  • IMPORT TEXT

Bei dynamischer Übergabe der Tabelle findet der Compiler manchmal nicht den Trigger zum Überprüfen heraus. Hierzu Beispiele:

 DEFAULT TABLE([Table_1])
 SAVE RECORD
 SAVE RECORD($ptrOnTable->)
 SAVE RECORD(Table(myMethodThatReturnsATableNumber())->)

In diesem Fall werden alle Trigger geprüft. Wird in mindestens einem Trigger ein thread-unsafe Befehl gefunden, wird die ganze Gruppe abgewiesen und die Methode als thread-unsafe deklariert.

Fehlerverwaltungsmethoden, die über den Befehl ON ERR CALL eingerichtet werden, müssen thread-safe sein, wenn sie von einem preemptive Prozess aufgerufen werden sollen. Für diesen Fall prüft der Compiler jetzt beim Kompilieren die Eigenschaft thread-safe der Fehlerverwaltungsmethoden im Befehl ON ERR CALL und gibt entsprechende Fehler zurück, wenn sie nicht zur preemptive Ausführung passen.

Beachten Sie, dass diese Prüfung nur möglich ist, wenn der Methodenname als Konstante übergeben ist und nicht berechnet wird, wie unten angezeigt:

 ON ERR CALL("myErrMethod1") //wird vom Compiler geprüft
 ON ERR CALL("myErrMethod"+String($vNum)) //wird vom Compiler nicht geprüft

Außerdem wird ab 4D v15 R5 der neue Fehler -10532 generiert, wenn sich eine Fehlerverwaltungsmethode nicht in Echtzeit aufrufen lässt (bei Unstimmigkeiten der Thread-Sicherheit oder aus einem anderen Grund, wie z.B. Methode wurde nicht gefunden). Die Fehlermeldung lautet: "Kann nicht die Projektmethode 'MethodeName' zur Fehlerverwaltung aufrufen".

Ein Prozess kann einen Zeiger nur dereferenzieren, um auf den Wert einer anderen Prozessvariable zuzugreifen, wenn beide Prozesse kooperativ sind. Sonst gibt 4D einen Fehler zurück. Versucht 4D Code in einem preemptive Prozess einen Zeiger auf eine Interprozessvariable zu dereferenzieren, gibt 4D einen Fehler aus.

Beispiel mit folgenden Methoden:

Methode1:

 myVar:=42
 $pid:=New process("Methode2";0;"Prozessname";->myVar)

Methode2:

 $value:=$1->

Ist der Prozess mit Methode1 oder der Prozess mit Methode2 preemptive, gibt der Ausdruck "$value:=$1->" einen Ausführungsfehler aus.

Der Parameter DocRef (geöffnete Dokumentreferenz, von Open document, Create document, Append document, CLOSE DOCUMENT, RECEIVE PACKET, SEND PACKET verwendet oder zurückgegeben) lässt sich folgendermaßen verwenden:

  • Bei Aufruf von einem preemptive Prozess ist DocRef nur von diesem preemptive Prozess verwendbar.
  • Bei Aufruf von einem kooperativen Prozess ist DocRef auch von anderen kooperativen Prozessen verwendbar.

Weitere Informationen dazu finden Sie im Abschnitt DocRef: Referenznummer des Dokuments.



Siehe auch 

Command name
Preemptive Web Prozesse verwenden

 
EIGENSCHAFTEN 

Produkt: 4D
Thema: Prozesse

 
GESCHICHTE 

Erstellt: 4D v15 R5

 
ARTIKELVERWENDUNG

4D Programmiersprache ( 4D v16.1)
4D Programmiersprache ( 4D v16.2)
4D Programmiersprache ( 4D v16.3)