[c++ unter linux] Mehrfachstarts meines Programms vermeiden

Molly_Grue

Mitglied
Hallo zusammen,

wie ihr im Betreff schon sehen könnt, möchte ich gern vermeiden, dass mein Programm mehrmals gestartet wird. Ich hab auch schon google bemüht, aber nichts gefunden, was mir weitergeholfen hätte. Vielleicht such ich mit den falschen Stichwörtern....

Naja, egal. Ich dachte, ich könnte es so umsetzen, alle laufenden Prozesse nach meinem zu durchsuchen (der Programmname steht ja in argv[0]) und je nach Ergebnis entweder wirklich starten oder halt mit ner Fehlermeldung beenden. Aber mir fehlt komplett ein brauchbarer Ansatz, mit dem ich irgendwie anfangen könnte... system() wollte ich dabei übrigens nach Möglichkeit vermeiden...

Hat jemand von euch vllt einen Hinweis für mich? Oder ein Stichwort, mit dem ich bei google fündig werde? ;) Wie gesagt, Entwicklungsumgebung ist Linux (Debian).

Vielen Dank schonmal,
Molly
 
Hallo,

das kann man auch einfacher über einen exclusiven "Datei-Lock" erreichen:

Du öffnest eine Datei mit dem Namen deines Programmes (bzw legst sie an falls es dies noch nicht geben sollte) und forderst einen Lock auf diese Datei an. Besitzt ein anderer Prozess schon den Lock, weißt du das dein Prozess nicht der einzige ist (wobei ich den Programmnamen als Dateinamen als hinreichend eindeutig einstufen würde):


C:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <errno.h>
#include <string.h>

char *
strrstr (char *haystack, char *needle)
{
  char *last_occur = NULL, *tmp = haystack;

  if (tmp != NULL)
    {
      while ((tmp = strstr (tmp + 1, needle)) != NULL)
        last_occur = tmp;
    }

  return last_occur;
}

int
main(int argc, char **argv)
{
  char lockfile[1048];
  char *prog_name;

  int fd = 0;

  prog_name = strrstr (argv[0], "/");
  if (prog_name != NULL)
    snprintf (lockfile, 1048, "/tmp/%s.lock", prog_name + 1);
  else
    snprintf (lockfile, 1048, "/tmp/%s.lock", argv[0]);

  /* open a lockfile */
  if ((fd = open (lockfile, O_CREAT | O_RDWR, S_IRWXU)) == -1)
    {
      perror ("Error in fopen");
      goto err;
    }

  /* require an exclusive lock on the file in non blocking mode */
  if (flock (fd, LOCK_EX | LOCK_NB) != 0)
    {
      /* if flock fails with error status EWOULDBLOCK  => we are not the only instance */
      if (errno == EWOULDBLOCK)
        fprintf (stderr, "An instance of this program is currently running! Exiting...\n");
      else
        perror ("Error in flock");
      goto err;
    }

  /* some useful computation */
  sleep (10);

  /* release the lock */
  if (flock (fd, LOCK_UN) != 0)
    {
      perror ("Error in flock!");
      goto err;
    }

  /* close the lockfile */
  close (fd);
  return 0;

err:
  close (fd);
  return 1;
}

siehe auch "man flock"
Gruß,
RedWing
 
Zuletzt bearbeitet:
Hallo RedWing,

vielen Dank, das mit dem lock ist ja echt ne super Sache! Besonders, da man auf diese Weise auch die Möglichkeit hat zu unterscheiden ob das Programm normal beendet wurde (lock-Datei mit z.B. unlink() löschen) oder ob es unerwartet beendet wurde (z.B. wegen einem Speicherzugriffsfehler *hüstel*), also die lock-Datei noch da, aber nicht mehr gesperrt ist. Ich weiß zwar grad nich ob ich diese Info wirklich brauche, aber ich finds schön, dass ich das feststellen kann, auch wenns vllt nur nen "HINT" im Log gibt... :)

Dankeschön nochmal, wieder was gutes gelernt ;)

Liebe Grüße,
Molly
 
Zurück