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 einoneway
-Aufruf ausgeführt und dann eine Nicht-oneway
-Instanz aufgerufen wird, kann der Serveroneway
- 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 mitReturn::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.