PDA

View Full Version : RPG: zu viele offene Descriptoren ????



Siggi_
13-01-09, 09:20
Hallo liebe Leser...

ich habe da ein mich belastendes Problem und hoffe, jemand erbarmt sich meiner...

Kurzbeschreibung(alles ILE-RPG, V5R4):
pgm A(actgrp=*new) ruft per Funktionsaufruf pgm B auf.
pgm B(Actgrp=*caller) ruft per Funktionsaufruf mehrfach srvpgm C auf.
srvpgm C(actgrp=*caller) erstellt eine pipe(API Qp0zPipe), holt sich eine Funktionsadresse aus einem anderen srvpgm D und führt diese Funktion dann aus. Die pipe dient zur Kommunikation zwischen pgm C und D.
Ist D fertig, liest C die Antwort aus der pipe, schliest diese und wird beendet(return, *inlr=*off).
Wenn nun A mehrfach aufgerufen wird, macht C irgendwann die Grätsche und sagt: zu viele offene Descriptoren für diesen Prozess !?!?!??!?!

Es scheint also so, daß trotz des Schließens der pipe die beiden descriptoren immer noch im "Hintergrund" da sind.
Wie werde ich die wieder los? Ist das wirklich das Problem? Ich hab schon 'ne kahle Stelle am Kopf...

Hoffentlich kann da jemand helfen...

Beispielcode kann ich natürlich liefern, ich müsste nur wissen, was genau benötigt wird.

Siggi

RobertMack
13-01-09, 10:39
return, *inlr=*off verlässt nur ... *inlr=*on beendet.

Siggi_
13-01-09, 11:09
Hallo Robert,

vielen Dank für deine Antwort. Der Unterschied ist mir bekannt...leider bleibt mir der Sinn Deiner Antwort unklar. Wahrscheinlich bin ich einfach mental blockiert;) Und bevor ich anfange zu interpretieren: vielleicht erlaubt es ja Deine Zeit nochmals ein wenig ausführlicher zu antworten, das wäre schön!

mfG
Siggi

B.Hauser
13-01-09, 11:10
Ich weiss jetzt nicht in wieweit ich durch den folgenden Vorschlag in Euer Design eingreife.

So wie es aussieht, werden mit jedem Aufruf der Prozedur aus Service-Program C statische Deskriptoren gebildet, die den Speicher blockieren und bei Beenden der Prozedur nicht freigeben.

*INLR = *ON wird auch nicht helfen, da der Speicher in einer ILE-Umgebung dadurch nicht freigegeben, sondern reserviert bleibt bis die Aktivierungsgruppe, in der das Programm oder Service-Programm läuft beendet wird.

Ich würde versuchen das Service-Programm C in einer benannten Aktivierungsgruppe (z.B. SrvPgm-Name = Aktivierungsgruppe) laufen lassen und nach jedem Aufruf diese Aktivierungsgruppe explizit mit dem CL-Befehl RCLACTGRP(SrvPgm) schließen. Dadruch müsste der Speicher freigegeben und die Deskriptoren wieder gelöscht werden. Wie sich das Ganze performancemäßig verhält bleibt auszuprobieren.

Eine andere Frage, die sich stellt:
Ist der Aufruf des APIs unbedigt erforderlich oder kann die Prozedur im 2.Service-Programm, die den Prozedur-Pointer zurückgibt nicht direkt aufgerufen werden?

Birgitta

Siggi_
13-01-09, 11:28
Hallo Birgitta,

auch Dir lieben Dank für Deine Antwort. Das srvpgm C war ursprünglich "nur" eine COPY-Strecke und wird auch als solche noch in manchen Programmen verwendet. Dort kommt es nicht zu diesem Problem. Leider kann ich aber, da wir auch gekaufte Software einsetzen, diese Copy-Strecke dort nicht nutzen...
Da es sich bei srvpgm C um ein (das) zentrale Ermittlungsprogramm für die angeforderte Funktion handelt, möchte ich da auf gar keinen Fall (Performance) mit einer benannten actgrp usw. arbeiten.
Es muß doch da noch einen anderen Weg geben!?

mfG
Siggi

Fuerchau
13-01-09, 12:07
Bei einer Pipe werden ja 2 Descriptoren geöffnet!
Bist du sicher, dass du auch beide schließt "close()-Funktion"?

Siggi_
13-01-09, 12:35
ja, bin mir sicher, daß beide geschlossen werden...

Fuerchau
13-01-09, 15:33
Soganz kann ich da was nicht nachvollziehen, aber:

Das Programm D muss ja wohl irgendwie das Handle der Pipe noch übergeben bekommen, sonst kann ja auf der Empfangsseite nichts ankommen.

Ich vermute daher mal, dass der Close nicht erfolgreich ist, da noch irgendeine Ressource belegt ist.

Wie erfolgt denn der Close ?

Siggi_
14-01-09, 10:25
Hallo zusammen...
vielen Dank für die Hilfe.
Ich habe es jetzt folgendermaßen gelöst: Alle Programm sind mit actgrp=*caller erstellt, alle werden nur mit return verlassen (*inlr=*off) und im srvpgm C erstelle ich die pipe nur, wenn sie nicht bereits vorhanden ist...
So scheint es jetzt zu funktionieren...

Siggi