Einzelnen Beitrag anzeigen

Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
744 Beiträge
 
#12

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 24. Aug 2014, 02:51
Zitat:
Nö. Wenn die ISAPI einmal geladen ist, verbleibt sie normalerweise im Speicher; es sei denn du setzt absichtlich den Registryeintrag "CacheExtensions" auf 0:
Ups! Ich habe da zwar - von Embaecadero - andere Infos:
Jede Anforderung wird in einem eigenen Thread behandelt.

Ich habe jetzt doch eine Weile gesucht und bislang nur oben verlinkte Seite gefunden, die meine Aussage unterstützt.
Da steht "eigner Thread". Und das ist korrekt. Aber es ist immer nur ein Prozess und daher ist es auch ein gemeinsamer Speicherbereich. Man muss lediglich mit den Speicherzugriffen aufpassen (kritische Abschnitte verwenden).

Zitat:
Aber vielleicht sollten ich doch mal ein Missverständnis ausräumen: Ich wollte nicht behaupten, dass die dll aus dem Speicher entfernt wird:
Zitat:
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet
Das stimmt so wirklich nicht. Es geht darum, dass ISAPI für jeden Request einen Thread startet - und dieser wird beendet, wenn die Anfrage fertig bearbeitet ist.
Ich bin mir jetzt nicht sicher, wie es bei ISAPI ist, aber wenn du eine "Webbroker-EXE" erstellst, gibt es einen Thread-Pool, d.h. es gibt auch dort mehrere Threads, die werden aber nicht sofort beendet, sondern werden der nächsten Anfrage (eines beliebigen Clients!) erneut zugeteilt. Macht daher letztlich keinen Unterschied, da der Client/Browser bei jeder Anfrage in einem anderen Thread landen kann. Wenn du also z.B. im Webmodul ein Dataset offen lässt, greift später ggf. ein ganz anderer Client auf dieses zu.

Zitat:
Zitat:
Globale Variablen sind grundsätzlich Pfui, da multithreaded, und müssen durch critical sections abgesichert werden. Aber als globale Variable brauchst du eigentlich nur eine SessionList (Liste, Array, Hashmap, ...). Diese ist durch eine CriticalSection abzusichern.
In die einzelnen Sessions (Session-Objekte) kannst du dann deine Daten, (Daten-)Objekte, Datenmodule etc. packen. Dabei muss ein Objekt oder Datenmodul für jede Session neu erstellt werden und es dürfen auch dort keine globalen Variablen, sondern nur Felder/Properties verwendet werden.
Es ist jetzt schon eine Weile her, dass ich selbst mit Threads gearbeitet habe. Was mir davon so aus dem Stegreif noch geblieben ist: ein Thread eines (Desktop-)Programmes kann nicht auf ein VCL-Objekt zugreifen, ausser durch Synchronisierung. Das aber kann den Performancevorteil eines Threads zunichte machen. Ein (Session-)Objekt müsste also dem Thread vor/beim Start übergeben werden.
Da du hier eh nicht mit visuellen Komponenten arbeiten kannst, macht es das schon mal etwas einfacher. Das Synchronize wird meist benutzt, um die Oberfläche/Forms anzupassen, das entfällt ja hier. Ansonsten benötigst du eigentlich nur eine globale Variable (oder besser eine Function oder noch besser eine Klassenmethode) mit einer "SessionList" über die du an ein bestimmtes Datenobjekt oder eine bestimmte Instanz eines Datenmoduls herankommst. Die Sessionlist und ggf. das Datenobjekt/Datenmodul musst du mit einer CriticalSection absichern, damit eben sicher gestellt ist, dass sich die Threads nicht in die Quere kommen. Wenn du mit Datenbanken arbeitest, musst du auch pro Session eine Datenbankverbindung aufbauen, wenn deine Datenbank-Connection-Komponente nicht explizit als Threadsafe gekennzeichnet ist.

Wenn also eine neue Anfrage in deinem Webmodul landet, musst du zuerst über die sessionList (unter Beachtung der CriticalSection!) aufrufen und dir darüber deine Daten für diese Session besorgen, bzw. einen neuen Eintrag in der Liste anlegen und eine neue Instanz der Datenstruktur erstellen, wenn es eine neue Session ist (der Client benötigt dann auch diese Session-ID und muss die beim nächsten mal mitsenden).

Zitat:
Ich hab jetzt gerade noch etwas in den Sourcen gestöbert. Bislang hatte ich geglaubt, durch die Verwendung der Isapi-Units, die Delphi mitliefert, würde ein Thread automatisch gestarte, konnte bislang aber keinen Code finden, der sowas macht...
Das passiert AFAIK irgendwo (tief) in den Indy-Komponenten.

Stimmt ja auch, ABER (s.o.): Thread != Prozess

Zitat:
Na ja, mir schwant, dass ein ausführliches Studium zuverlässiger als die Embarcadero-Help ist...
Waren scheinbar nur die Begrifflichkeiten. Aber sowas passiert mir in anderen Fällen auch ständig.

Zitat:
Das mit den globalen Variablen war mir bekannt: Das war für mich einer, wenn nicht gar der Hauptgrund, für eine EXE.
Da hilft dir eine "Webbroker-EXE" aber auch nicht weiter, da es dort das Gleiche mit den Threads ist (s.o.). Und ein CGI ist sogar ein eigener Prozess, also noch weniger für dich geeignet.


Gruß,
Olli
  Mit Zitat antworten Zitat