Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
Konsolenaufruf und SIGNAL

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
grisu1972



Anmeldungsdatum: 22.07.2008
Beiträge: 16

BeitragVerfasst am: 22. Jul 2008 12:12   Titel: Konsolenaufruf und SIGNAL

Hallo Leute,

habe folgendes Problem:
Aus einer Applikation (App1) heraus wird mittels system(aufruf) eine zweite Applikation (App2) gestartet.
Ich möchte verhindern, das dies Applikation App2 mehrmals aus App1 gestartet werden kann! Und ich möchte aus App1 an App2 ein Signal schicken wenn ein zweites mal versucht wird App2 zu starten.

Leider bekomme man bei dem Aufruf von System nicht die PID zurück sondern nur ob es geklappt hat oder nicht!

Für den Signalhandler benötige ich aber die PID!
Aber wie ermittele ich diese am besten?

Kann mir jemand helfen?
 
Benutzer-Profile anzeigen Private Nachricht senden

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 22. Jul 2008 16:35   Titel:

system() ist für sowas ungeeignet, da der aufrufende Prozess wartet, bis das aufgerufene Programm beendet ist. system() ist eine Abkürzung für "naive" Prozesse, die nichts vom Multitasking wissen müssen -- system() ist im C-Standard definiert und muss also auch z.B. unter DOS funzen.

Nimm stattdessen fork() und execve(), wenn du die Unix-Semantik brauchst.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

grisu1972



Anmeldungsdatum: 22.07.2008
Beiträge: 16

BeitragVerfasst am: 23. Jul 2008 15:46   Titel:

Hallo Leute,

ich durchsuche das /proc Verzeichnis nach meinem Prozess.
Dabei habe ich das Problem, dass dort der Name exe lautet und mit meiner Applikation verlinkt ist!

Wie bekomme ich aus dem link namen den "richtigen" Namen?
 
Benutzer-Profile anzeigen Private Nachricht senden

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 23. Jul 2008 22:44   Titel:

$ man 2 readlink

Aber das ist sowieso der falsche Weg. Der richtige Weg ist es, sich mit flock() ein Lock auf das Executable der Applikation zu beschaffen und auf *dieses* zu testen, nicht auf den *Namen* der Applikation.

So in etwa:
Code:

  if ((app_fd=open("/proc/self/exe", O_RDONLY)) == -1) {
    perror("cannot lock against multiple invocation");
    exit(EXIT_FAILURE);
  }
  if (flock(app_fd, LOCK_EX) == -1) {
    perror("cannot lock against multiple invocation");
    exit(EXIT_FAILURE);
  }

Im Beispiel oben wartet eine Applikation im flock() so lange, bis ihre Schwester mit dem gleichen Executable beendet wurde. Und das vollautomatisch!

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

grisu1972



Anmeldungsdatum: 22.07.2008
Beiträge: 16

BeitragVerfasst am: 25. Jul 2008 8:44   Titel:

Aber das löst mein Problem nicht(zumindest ist es mir nicht gelungen!)!

Vorgehensweise:
- einen filedescriptor fd
- darauf führe ich ein lock aus, wenn ich diese Applikation starten will.
Dieses muss "flock (fd, LOCK_EX| LOCK_NB)" sein weil die zweite Applikation nur einmal gestartet werden soll und beim zweiten aufruf nichts passieren soll!

Problem ist, dass die zweite Applikation aus dem gleichen Prozess (erste Applikation) heraus mehrmals gestartet werden kann!

Oder habe ich das Konzept nicht verstanden?
 
Benutzer-Profile anzeigen Private Nachricht senden

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 25. Jul 2008 9:31   Titel:

So wie du es machen willst, kann du es folgendermaßen tun:

fd muss ein Filedeskriptor auf das Executeable der zweiten Applikation sein, also nicht wie bei mir auf /proc/self/exe, sondern auf <Pfad zum Executeable der zweiten Applikation>. Den hast du ja sowieso, weil du danach execve() machen willst.

Dann machst du, wie du richtig rausgefunden hast, ein flock(fd, LOCK_EX|LOCK_NB) und guckst, ob EWOULDBLOCK zurückkommt. Wenn ja, machst du gar nichts, wenn nein, kannst du die andere Applikation starten. Das funktioniert natürlich nur mit kooperativen Prozessen, d.h. Applikation 2 muss grundsätzlich aus Applikation 1 heraus aufgerufen werden, weil ja sonst das Lock nicht abgefragt wird. Da du ja nicht genauer geschrieben hast, was Applikation 1 und Applikation 2 sind, gehe ich von kooperativen Prozessen aus.

Grundsätzlich hast du mit deiner Vorgehensweise aber das Problem, dass zwischen dem Abfragen, ob die zweite Applikation bereits gestartet ist und dem Moment, wo du die zweite Applikation startest ein Loch besteht, in dem die zweite Applikation bereits von extern gestartet werden konnte. Das ist sehr wackelig programmiert.

Deshalb ist es grundsätzlich ratsam, dass eine Applikation immer *selbst* prüft, ob bereits ein anderer Prozess mit demselben Executable gestartet wurde und danach blockiert oder sich selbst gleich wieder beendet. So entsteht kein Loch.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy