Modell-Threading

Methoden, die als oneway gekennzeichnet sind, werden nicht blockiert. Für Methoden, die nicht als oneway wird der Methodenaufruf eines Clients blockiert, bis der Server abgeschlossene Ausführung oder als synchrones Callback bezeichnet werden (je nachdem, was zuerst eintritt). Implementierungen von Servermethoden können höchstens einen synchronen Callback aufrufen. Extra Callback-Aufrufe werden verworfen und als Fehler protokolliert. Wenn eine Methode gibt Werte über einen Callback zurück und ruft dessen Callback nicht auf. Dies wird als Fehler und als Transportfehler an den Client gemeldet.

Threads im Passthrough-Modus

Im Passthrough-Modus sind die meisten Aufrufe synchron. Um jedoch den dass oneway-Aufrufe den Client nicht blockieren, für jeden Prozess erstellt wird. Weitere Informationen finden Sie in der HIDL-Übersicht

Threads in binderisierten HALs

Um eingehende RPC-Aufrufe (einschließlich asynchroner Rückrufe von HALs an HAL-Nutzern) und Benachrichtigungen bei Todesfällen, ist jedem Prozess ein Threadpool zugeordnet. mit HIDL. Wenn ein einzelner Prozess mehrere HIDL-Schnittstellen und/oder Handler für Todesbenachrichtigungen arbeiten, wird ihr Threadpool von allen Handlern gemeinsam genutzt. Wann? ein Prozess einen eingehenden Methodenaufruf von einem Client empfängt, wählt er einen kostenlosen Thread aus. und führt den Aufruf in diesem Thread aus. Wenn kein kostenloser Thread vorhanden ist wird es blockiert, bis eine verfügbar ist.

Wenn der Server nur einen Thread hat, sind Aufrufe an den Server abgeschlossen in der richtigen Reihenfolge. Ein Server mit mehr als einem Thread führt möglicherweise Aufrufe in falscher Reihenfolge durch auch wenn der Client nur einen Thread hat. Für ein bestimmtes Interface-Objekt oneway Aufrufe werden garantiert sortiert (siehe Server-Threading-Modell). Bei einem Multithread-Server, hostet mehrere Schnittstellen, oneway-Aufrufe an verschiedene Schnittstellen gleichzeitig mit anderen oder anderen blockierenden Aufrufen verarbeitet werden.

Mehrere verschachtelte Aufrufe werden im selben hwbinder-Thread gesendet. Beispiel: wenn ein Prozess (A) einen synchronen Aufruf von einem hwbinder-Thread zu Prozess (B) durchführt, und Prozess (B) anschließend einen synchronen Aufruf zu Prozess (A) durchführt, wird der Aufruf ausgeführt auf dem ursprünglichen hwbinder-Thread in (A), der im ursprünglichen Thread blockiert ist aufrufen. Durch diese Optimierung kann ein einzelner Thread-Server verschachtelte Aufrufe verarbeiten, aber das gilt nicht für Fälle, in denen eine weitere Abfolge von IPC-Aufrufen. Wurde beispielsweise bei Prozess (B) eine binder/vndbinder-Aufruf, der einen Prozess-Aufruf (C) und dann einen Prozess-Aufruf (C) aufruft. wieder in (A) zurück, kann sie nicht im ursprünglichen Thread in (A) bereitgestellt werden.

Server-Threading-Modell

Mit Ausnahme des Passthrough-Modus werden Serverimplementierungen von HIDL-Schnittstellen live geschaltet. in einem anderen Prozess als der Client durchgeführt werden und eingehende Methodenaufrufe. Diese Threads sind der Threadpool des Servers. kann der Server festlegen, wie viele Threads in seinem Thread-Pool ausgeführt werden sollen, und einen Threadpool-Größe von eins, um alle Aufrufe auf seinen Schnittstellen zu serialisieren. Wenn der Server mehr als einen Thread im Threadpool hat, kann er gleichzeitig eingehende an beliebiger Stelle aufgerufen wird (in C++ bedeutet dies, dass freigegebene Daten sorgfältig gesperrt).

Einwegaufrufe in dieselbe Schnittstelle werden serialisiert. Wenn eine Multithread- Client ruft method1 und method2 auf der Schnittstelle auf IFoo und method3 auf Schnittstelle IBar, method1 und method2 sind immer serialisiert, aber method3 kann parallel mit method1 ausgeführt werden und method2.

Ein einzelner Client-Thread der Ausführung kann zur gleichzeitigen Ausführung auf einem mit mehreren Threads auf zwei Arten verbinden:

  • oneway-Anrufe werden nicht blockiert. Wenn ein oneway-Aufruf ausgeführt und dann eine Nicht-oneway-Instanz aufgerufen wird, kann der Server oneway- und Nicht-oneway-Aufruf gleichzeitig.
  • Bei Servermethoden, die Daten mit synchronen Callbacks zurückgeben, kann die Blockierung aufgehoben werden. sobald der Callback vom Server aufgerufen wird.

Zweitens kann jeder Code in der Serverfunktion, der nach der Callback aufgerufen wird, kann gleichzeitig ausgeführt werden, wobei der Server vom Client gesendet wird. Dazu gehört Code in der Serverfunktion und Destruktoren, die am Ende der Funktion ausgeführt werden. Wenn auf dem Server mehr als in seinem Threadpool vorhanden ist, treten Gleichzeitigkeitsprobleme auf, auch wenn Anrufe aus einem einzigen Client-Thread. (Wenn ein von einem Prozess bereitgestellter HAL mehrere Threads haben, haben alle HALs mehrere Threads, da der Threadpool pro Prozess geteilt werden.)

Sobald der Server den bereitgestellten Callback aufruft, kann der Transport die implementierten Callback auf dem Client und hebt die Blockierung auf. Der Kunde fährt fort. parallel zu den Aktionen, die bei der Serverimplementierung ausgeführt werden, nachdem sie die Callback (die Ausführung von Destruktoren enthalten kann). Code in der Serverfunktion nachdem der Callback den Client nicht mehr blockiert (solange der Server Threadpool verfügt über genügend Threads, um eingehende Anrufe zu verarbeiten, kann aber ausgeführt werden. zukünftigen Aufrufen vom Client gesendet werden (es sei denn, der nur einen Thread).

Zusätzlich zu synchronen Callbacks ruft oneway von einem Single-Threaded-Client kann gleichzeitig von einem Server mit mehreren Threads im Threadpool befinden, aber nur, wenn diese oneway-Aufrufe die auf verschiedenen Schnittstellen ausgeführt werden. oneway Anrufe gleichzeitig immer serialisiert.

Hinweis:Für Serverfunktionen wird dringend empfohlen, zurückgegeben, sobald sie die Callback-Funktion aufgerufen haben.

Zum Beispiel (in C++):

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    // At this point, the client's callback is called,
    // and the client resumes execution.
    ...
    return Void(); // is basically a no-op
};

Client-Threading-Modell

Das Threading-Modell auf dem Client unterscheidet sich bei nicht blockierenden Aufrufen (Funktionen, die mit dem Schlüsselwort oneway gekennzeichnet sind) und blockieren Aufrufe (Funktionen, für die das Schlüsselwort oneway nicht angegeben ist).

Anrufe blockieren

Bei einer Blockierung von Aufrufen wird der Client blockiert, bis eines der folgenden Ereignisse eintritt:

  • Transportfehler tritt auf. Das Objekt Return enthält einen Fehler. , der mit Return::isOk() abgerufen werden kann.
  • Die Serverimplementierung ruft den Callback auf (falls vorhanden).
  • Bei der Serverimplementierung wird ein Wert zurückgegeben, wenn kein Callback-Parameter vorhanden ist.

Im Erfolgsfall lautet die Callback-Funktion, die der Client als Argument übergibt, immer vom Server aufgerufen, bevor die Funktion selbst zurückgegeben wird. Der Callback ist die auf demselben Thread ausgeführt werden, an dem der Funktionsaufruf erfolgt. muss beim Halten von Sperren während Funktionsaufrufen vorsichtig sein (und sie vermeiden wenn möglich. Eine Funktion ohne generates-Anweisung oder ein oneway-Keyword immer noch blockiert wird, blockiert der Kunde, Server gibt ein Return<void>-Objekt zurück.

Anrufe in eine Richtung

Wenn eine Funktion als oneway gekennzeichnet ist, gibt der Client sofort eine Antwort zurück. und wartet nicht, bis der Funktionsaufruf vom Server abgeschlossen ist. Im (und insgesamt) bedeutet dies, dass der Funktionsaufruf weil es nur halb so viel Code ausführt. Aber beim Schreiben von Implementierungen, leistungssensibel sind, hat dies einige Auswirkungen auf die Planung. Normalerweise Bei Verwendung eines Einwegaufrufs wird der Anruf weiterhin angesetzt, führt ein normaler synchroner Aufruf dazu, vom Aufrufer an den aufgerufenen Prozess übergeben. Dies ist eine Leistungsoptimierung in binder. Für Dienste, bei denen der Einwegaufruf im Zielprozess ausgeführt werden muss mit hoher Priorität kann die Planungsrichtlinie des empfangenden Dienstes geändert. In C++ mit der Methode von libhidltransport setMinSchedulerPolicy durch die Planerprioritäten und -richtlinien die in sched.h definiert ist, sorgt dafür, dass alle Aufrufe des Dienstes mindestens nach der festgelegten Planungsrichtlinie und Priorität.