Programm sperren

Moderator: Moderatoren

Antworten
Jojo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: So, 22. Jul 2012 13:44

Programm sperren

Beitrag von Jojo »

Hallo zusammen,

habe mal wieder ein Problem...

Ich möchte einen Programmteil während der Benutzung für andere User sperren.

Dazu habe ich eine Variable t_est deklariert...

Code: Alles auswählen

t_est := ''
, welche zuerst abgefragt wird:

Code: Alles auswählen

do case
case t_est = 0
@ 1,10 say 'Programm gesperrt!'
wait(20)
return ( .f. )
endcase

t_est = 0

Programmablauf...

t_est = 1
.

Weshalb bekomme ich einen Runtime error "data type mismatch in equals '= or ==' operation" ?

Hat jemand eine Idee, bzw. eine bessere Idee, wie ich ein Programm während der Benutzung für andere sperre?

Grüße
Jojo
Benutzeravatar
mini990
1000 working lines a day
1000 working lines a day
Beiträge: 592
Registriert: Sa, 28. Jan 2006 9:44
Wohnort: Berg-Richtheim bei Neumarkt i.d.Opf.
Danksagung erhalten: 1 Mal

Re: Programm sperren

Beitrag von mini990 »

Du weist der Variablen t_est einen Characterwert zu : t_est= ''
Danach fragst Du numerisch ab.
Daher der Datentypfehler...

Gruß Stefan
Jojo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: So, 22. Jul 2012 13:44

Re: Programm sperren

Beitrag von Jojo »

Hallo Stefan,

und wie weise ich der Variablen einen nummerischen Wert zu?

Grüße
Jojo
Zuletzt geändert von Jojo am Do, 10. Sep 2015 17:10, insgesamt 1-mal geändert.
Jojo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: So, 22. Jul 2012 13:44

Re: Programm sperren

Beitrag von Jojo »

O.K., dass war blöd gefragt...

Das ich mit t_est = 1 einen Wert zuweisen kann ist mir klar... :-)

Aber, wie weise ich der Variablen einen nummerischen Wert zu, ohne diese zu definieren?

Grüße
Jojo
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Wolfgang Ciriack »

Das wird so nicht klappen, denn jeder PC betreibt sein eigenes Programm und somit auch seine eigenen Variablen.
Ohne einen Wert in einer gemeinsam zugänglichen Datei (Datenbank oder andere Datei) wirst du nicht weiterkommen.
Erzeuge einfach beim Start des Programms eine leere Datei (z.B. InUse.myprog) und behalte sie offen, bis der Programmteil beendet ist, dann schließe und lösche Sie. Beim Start des Programms versucht du nun die InUse.myprog zu löschen. War es erfolgreich oder sie existiert nicht, dann kannst du in das Programm rein, ansonsten ist es in Benutzung.
Ich mache das so um zu ermitteln, wer und wieviele Benutzer mit meinem Programm arbeiten und so eine Benutzeranzahl einzuhalten. Klappt sehr gut, selbst wenn das Programm abstürzen sollte, dann kann die Datei eben gelöscht werden, da sie ja nicht mehr vom Programm offengehalten wird.
Viele Grüße
Wolfgang
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Programm sperren

Beitrag von AUGE_OHR »

Jojo hat geschrieben:Dazu habe ich eine Variable t_est deklariert...

Code: Alles auswählen

t_est := ''
, welche zuerst abgefragt wird:

Code: Alles auswählen

do case
case t_est = 0
@ 1,10 say 'Programm gesperrt!'
wait(20)
return ( .f. )
endcase

t_est = 0

Programmablauf...

t_est = 1
.

Weshalb bekomme ich einen Runtime error "data type mismatch in equals '= or ==' operation" ?
die Frage ist in welcher Zeile der Fehler gemeldet wird ?

p.s. eine Zuweisung "sollte" man mit := machen während = für einen Vergleich gedacht ist.
gruss by OHR
Jimmy
Jojo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: So, 22. Jul 2012 13:44

Re: Programm sperren

Beitrag von Jojo »

Hallo Wolfgang,

das werde ich versuchen und Rückmeldung über den Erfolg (oder eben auch Misserfolg ;-)) geben.
Vielen Dank!

@ Jimmy: Der "Type mismatch-Fehler" wird bei der Zeile "case t_est = 0" gemeldet.

Grüße
Jojo
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Rolf Ramacher »

oder du löst das ganze über eine Datenbank in der du Information einträgst
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von satmax »

Schnellschuss: mit
case t_est == 0
vergleicht man.

case t_est = 0 kann je nach Compilerlaune eine Zuweisung oder ein Vergleich sein.


Achja, auf Datentyp achten:
nicht t_est := '' sondern t_est := 0 // oder 1
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

Wenn mehrere laufenden Programme eventuell noch auf verschiedenen Rechnern aufeinander reagieren sollen, kann man das nur durch Sperrung externer sachen erledigen.
Mutex oder Semaphore sind Schlagworte in die Richtung, für uns viel einfacher ist eine DBF, die geshared geöffnet wird, und für den Ausschluß anderer einen FLOCK() verwendet.
In der DBF mit einem Datensatz schreibt der sperrende seinen Rechnernamen, alle anderen können lesen wer sperrt, aber sonst nix tun.
Ein Absturz des sperrenden Rechners würde die Sperre automatisch aufheben.
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Tom »

Äh. Bei Mutexen geht es um Prozesssynchronisation (Zugriff auf gleiche Speicherbestandteile aus unterschiedlichen Applikationen). Wir sprechen hier aber von unabhängigen Arbeitsplätzen. "Semaphore" ist da das korrektere Stichwort.

Im einfachsten Fall erzeugt man eine Flag-Datei, die anderen Instanzen signalisiert, dass sie derzeit nicht starten dürften (oder sich sogar beenden, wenn sie gefunden wird). Die Flag-Datei - also die Semaphore - wird gelöscht, wenn der Prozess beendet ist. Zusätzlich muss es die Möglichkeit geben, sie von anderswo zu löschen, wenn der Prozess gescheitert ist oder es zu einem Fehler kam.
Herzlich,
Tom
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von satmax »

Habe einfach zu wenig genau gelesen. Das mit Zuweisung und Vergleich wurde ja schon gesagt. Ja, das mit den Semaphore mache ich genau so. Es wird eine Datei angelegt und gelockt. So lange diese Date existiert und nicht gelöscht/gelockt werden kann ist gesperrt. Stürzt das Programm das den Lock auf die Datei hat ab, wird der Lock vom Betriebssystem automatisch freigegeben.
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

Tom hat geschrieben:Wir sprechen hier aber von unabhängigen Arbeitsplätzen. "Semaphore" ist da das korrektere Stichwort.
da bin ich mir aus der Aufgabenstellung nicht so sicher, ein Terminalserver der mehrere Anwender bedient läuft auch auf der gleichen Maschine ...
Die Aufgabenstellung ist da - finde ich - ungenau, aber egal wie, ich würde es eh über die Dateisperre machen :-)
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Tom »

Oh, diese Lösung würde ich gerne sehen, wie mehrere Instanzen einer Anwendung auf einem Terminal Server über Mutexe kommunizieren. :wink: Machbar ist es sicher.

Eine Semaphorendatei ist tatsächlich die simpelste Lösung. Man muss nur darauf achten, sie wirklich wieder zu löschen, und ggf. Mechanismen bereitstellen, die das von außen oder beim Versuch eines Programmstarts erlauben (Admin darf es, keiner sonst oder so). Ergänzend sollte sie eine Gültigkeit haben. Eine Semaphorendatei von vorgestern sollte heute nicht mehr das Programm sperren. Das sind insgesamt vielleicht zwanzig Zeilen Code mit allem Pipapo.
Herzlich,
Tom
Benutzeravatar
mini990
1000 working lines a day
1000 working lines a day
Beiträge: 592
Registriert: Sa, 28. Jan 2006 9:44
Wohnort: Berg-Richtheim bei Neumarkt i.d.Opf.
Danksagung erhalten: 1 Mal

Re: Programm sperren

Beitrag von mini990 »

habe sowas vor Jahren mal auf diesem Weg gelöst:
Beim Programmstart wird abgefragt ob die Datei "InUse" existiert.
Wenn nicht:
Das startende Programm schreibt eine kleine Textdatei "InUse"
Beim Beenden wird die Datei gelöscht.
Fertig.
Hat funktioniert....

Gruß Stefan
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

Das mit Datei schreiben und löschen hat früher einwandfrei funktioniert, aber seit die Dateisysteme entscheiden,
wann sie tatsächlich nachsehen oder nur cache Daten liefern ist das nicht mehr zuverlässig.

Ein FLock() auf eine offene DBF ist noch (relativ) zuverlässig ;-)
Gruß
Hubert
Jojo
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 48
Registriert: So, 22. Jul 2012 13:44

Re: Programm sperren

Beitrag von Jojo »

Hallo zusammen,

hier die "angedrohte" Rückmeldung...

Nachdem das mit der Variablen nicht funktionierte und ich (ehrlich gesagt) nicht wusste, wie ich eine Datei erzeuge :-( , habe ich eine im Programm bereits des Öfteren verwende Variante gewählt.

Ich habe eine erfassung.dbf angelegt und frage diese am Anfang ab...

Code: Alles auswählen

select 7
use erfassung
 do while ! rec_lock( 2 )
    k_warn(' ABRUCH! Es wird momentan erfasst!' )
    RETURN( .f. )
 enddo

Programmablauf...

dbclosearea(7)
Damit bekommt ein User, während ein anderer in der Erfassung ist, die Meldung das er nicht weitermachen kann und alles ist i.O. :-)

Einzig das Problem bei einem Programmabsturz, bekomme ich so nicht im Griff.
Beim Testen habe ich gemerkt, das wenn ich ohne korrekten Abschluß aus dem Programm gehe, die Erfassung gesperrt bleibt.

Aber da es sich um einen Programmabschnitt handelt, der nur im sehr seltenen Notfall zum Einsatz kommt, kann ich damit leben, außerdem kann ich ja auch aus der Ferne eingreifen.

Vielen Dank an alle für die, wie immer, hilfreichen Tipps. :-D

Grüße
Jojo
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

Jojo hat geschrieben:ich (ehrlich gesagt) nicht wusste, wie ich eine Datei erzeuge
In Xbase++ ich meine das ging auch schon bei clipper ...

Code: Alles auswählen

if ! file(cSteuFile)
   aStru := { { "PCID","c",20,0 } }
   dbcreate( cSteuFile, aStru )
endif
Gruß
Hubert
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Wolfgang Ciriack »

Hier mal einfacher Ablauf mit beliebiger Datei (ungetestet). Hat den Vorteil, das es auch bei einem zwischenzeitlichem Absturz des Programms funktioniert.

Code: Alles auswählen

d:="InUse.myprog"
if (nFH:=ChkProgFree())>0
... meine Procedure.....
    FClose(nFH)
    FErase(d)
else
    *** gesperrt
endif

function ChkProgFree(d)
if FExist(d)
   FErase(d)
endif
if FExist(d)
   * Existiert noch immer (konnte nicht gelöscht werden, da in Benutzung)
   ** Programm gesperrt
 endif
nFH:=FCreate(d)
return nFH
Viele Grüße
Wolfgang
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Tom »

Ansonsten auch MemoWrit(), die Low-Level-Funktionen (FCreate u.ä.) sowie StrFile() aus den Tools. Alle wären auch dazu in der Lage, Binärdaten zu schreiben.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

Jojo hat geschrieben: Einzig das Problem bei einem Programmabsturz, bekomme ich so nicht im Griff.
Beim Testen habe ich gemerkt, das wenn ich ohne korrekten Abschluß aus dem Programm gehe, die Erfassung gesperrt bleibt.
Bei Clipper und Xbase++ wird eine offende Datei definitiv geschlossen, wenn das Programm abstürzt.
Dabei werden auch alle LOCKS auf die Datei aufgehoben.

Ich kann mir nicht vorstellen, dass das bei Flagship anders sein soll !
Gruß
Hubert
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Wolfgang Ciriack »

@Hubert,
er meint, wenn er in der Datenbank "in Benutzung" gesetzt hat und dann das Programm abstürzt, dann bleibt natürlich in der DBF das erhalten. Deswegen auch mein Vorschlag, mit einer geöffneten Datei.
Viele Grüße
Wolfgang
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von brandelh »

"In Benutzung gesetzt" ... ok wenn er das über einen Feldinhalt regelt muss es schief laufen.
Ich meinte die Steuerung über die Dateisperre zu regeln

Code: Alles auswählen

use logfile shared alias LOG NEW // am Programmanfang, immer offen, NEW öffnet unter Xbase++ in leerem Select-Bereich
...
IF LOG->(FLock()) // NICHT irgendwelche NET... lock Konstuktionen, weil wir genau einen Versuch möchten !
   // Ich konnte sperren, also darf ich als einziger darauf schreiben
   replace LOG->RechnerID with netname() // so könnte man den Rechner speichern der zuletzt Schreibrechte erhalten hat
   LOG->(dbGoBottom())
   LOG->(dbGoTop())
   ...
ELSE 
   // Fehlgeschlagen, es muss schon in bearbeitung sein 
   ? "Datei in Bearbeitung auf: " + LOG->RechnerID
ENDIF 
Sobald das Programm abstürzt, werden alle Dateien geschlossen und die Bearbeitung automatisch freigegeben.
Gruß
Hubert
Leon
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 118
Registriert: Mi, 28. Nov 2007 12:48
Wohnort: Wien
Hat sich bedankt: 5 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Leon »

Tom hat geschrieben:Ansonsten auch MemoWrit(), die Low-Level-Funktionen (FCreate u.ä.) sowie StrFile() aus den Tools. Alle wären auch dazu in der Lage, Binärdaten zu schreiben.
Bei StrFile() aus den Tools scheint es einen Bug zu geben. Unter Windows 8.1 und Windows 10 wird zwar eine Datei erstellt, allerdings mit der Länge 0 Bytes und natürlich ohne Inhalt.
Gruß aus Wien
Leon
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Programm sperren

Beitrag von Wolfgang Ciriack »

Kann ich nicht bestätigen, bei mir klappt es, benutze es öfters ohne Probleme.
Viele Grüße
Wolfgang
Antworten