Checking for duplicate instances - Unix

This is a discussion on Checking for duplicate instances - Unix ; Hello all. I'm currently looking for the following trick to do in Posix C: a way to test if there is another instance of the current program already running. In my usual (LabWindows) API, I call the following function at ...

+ Reply to Thread
Results 1 to 9 of 9

Thread: Checking for duplicate instances

  1. Checking for duplicate instances

    Hello all.

    I'm currently looking for the following trick to do in Posix C: a way to
    test if there is another instance of the current program already running.

    In my usual (LabWindows) API, I call the following function at the start of
    the program's execution:
    Status = CheckForDuplicateAppInstance (ACTIVATE_OTHER_INSTANCE,
    &ThereIsAnother);

    What is the Posix equivalent ?
    I'd like to avoid doing "ps | grep" at the shell level and keep everything
    in C.
    Thanks.
    --
    Guillaume Dargaud
    http://www.gdargaud.net/



  2. Re: Checking for duplicate instances

    On Nov 6, 12:49*am, "Guillaume Dargaud"
    wrote:

    > I'm currently looking for the following trick to do in Posix C: a way to
    > test if there is another instance of the current program already running.
    >
    > In my usual (LabWindows) API, I call the following function at the start of
    > the program's execution:
    > Status = CheckForDuplicateAppInstance (ACTIVATE_OTHER_INSTANCE,
    > &ThereIsAnother);
    >
    > What is the Posix equivalent ?
    > I'd like to avoid doing "ps | grep" at the shell level and keep everything
    > in C.


    There is no "one right way". The right way depends on your outer
    problem. What would go wrong if two instances were to run? Why should
    what Jack is doing affect what Jill is doing?

    DS

  3. Re: Checking for duplicate instances

    > There is no "one right way". The right way depends on your outer
    > problem. What would go wrong if two instances were to run? Why should
    > what Jack is doing affect what Jill is doing?


    OK, let's narrow down the issues:
    it's on a single user (root) embedded system, but the prog can be started on
    boot (by init.d) or manually from a serial console or an ssh login. In that
    case I just want a way to tell the guy he forgot to kill the previous
    instance.
    The one issue I see is if I update the executable while one is running. The
    new one has the some filename, although a different inode.
    --
    Guillaume Dargaud
    http://www.gdargaud.net/



  4. Re: Checking for duplicate instances

    "Guillaume Dargaud"
    writes:

    >> There is no "one right way". The right way depends on your outer
    >> problem. What would go wrong if two instances were to run? Why should
    >> what Jack is doing affect what Jill is doing?

    >
    > OK, let's narrow down the issues:
    > it's on a single user (root) embedded system, but the prog can be started on
    > boot (by init.d) or manually from a serial console or an ssh login. In that
    > case I just want a way to tell the guy he forgot to kill the previous
    > instance.


    A traditional method is this: create a file in /var/run called
    myprog.pid and containing the program's PID. Install signal handlers
    for common signals (SIGINT, SIGTERM, SIGHUP, etc) that remove the file.

    When the program starts, if the file exists, and a process with that PID
    is running (you can test this with kill(pid, 0)) then the program is
    most likely already running; otherwise, it's probably not, and you can
    create the file and continue.

    There are ways this can go wrong, but they're not likely.

    Another possible approach might be to have a lockfile in /var/lock or
    something. Upon starting, you create the file if it doesn't exist, then
    try to acquire an exclusive lock on it (using flock(fd, LOCK_EX |
    LOCK_NB) for example). If you succeed then all is well; if you fail
    then the program is already running. This is probably a bit more reliable.

    > The one issue I see is if I update the executable while one is running. The
    > new one has the some filename, although a different inode.


    Huh?

  5. Re: Checking for duplicate instances

    On Nov 6, 2:07*am, "Guillaume Dargaud"
    > OK, let's narrow down the issues:
    > it's on a single user (root) embedded system, but the prog can be startedon
    > boot (by init.d) or manually from a serial console or an ssh login. In that
    > case I just want a way to tell the guy he forgot to kill the previous
    > instance.
    > The one issue I see is if I update the executable while one is running. The
    > new one has the some filename, although a different inode.


    If it 'bind's a port, there's nothing special you need to do. The
    second instance will fail to bind.

    If it does not, the best solution is probably to have the program
    acquire some kind of exclusive lock on a resource such that both
    instances can't have the exclusive lock. Locking a PID file in a known
    location is one way to do this.

    DS

  6. Re: Checking for duplicate instances

    Nate Eldredge writes:
    > "Guillaume Dargaud"
    > writes:
    >
    >>> There is no "one right way". The right way depends on your outer
    >>> problem. What would go wrong if two instances were to run? Why should
    >>> what Jack is doing affect what Jill is doing?

    >>
    >> OK, let's narrow down the issues:
    >> it's on a single user (root) embedded system, but the prog can be started on
    >> boot (by init.d) or manually from a serial console or an ssh login. In that
    >> case I just want a way to tell the guy he forgot to kill the previous
    >> instance.

    >
    > A traditional method is this: create a file in /var/run called
    > myprog.pid and containing the program's PID. Install signal handlers
    > for common signals (SIGINT, SIGTERM, SIGHUP, etc) that remove the file.
    >
    > When the program starts, if the file exists, and a process with that PID
    > is running (you can test this with kill(pid, 0)) then the program is
    > most likely already running; otherwise, it's probably not, and you can
    > create the file and continue.
    >
    > There are ways this can go wrong, but they're not likely.


    You never had to debug a postfix-installation where one of the
    servers would not start after a reboot, because the pid stored in its
    pid-file was low enough that usually, by the time the postfix start
    script ran, there was already another process running with this pid,
    have you?

    That's already enough to convince someone whose main field of
    experience is using Windows on the desktop that a reinstall of the OS
    is required to 'fix' the problem.


  7. Re: Checking for duplicate instances

    > If it does not, the best solution is probably to have the program
    > acquire some kind of exclusive lock on a resource such that both
    > instances can't have the exclusive lock. Locking a PID file in a known
    > location is one way to do this.


    Thank you all for the detailed examples.
    I use GPIO resources, but I'm not sure if they are exclusive. I'll test it
    out and try to go that way.
    --
    Guillaume Dargaud
    http://www.gdargaud.net/



  8. Re: Checking for duplicate instances

    Is this a correct way to proceed ?

    fd = open(DevicePath, O_RDWR | O_NONBLOCK);
    struct flock lock;
    err = fcntl(fd, F_GETFL, &lock);
    lock.l_type=F_WRLCK;
    err = fcntl(fd, F_SETFL, &lock);
    if (err==0) ; // No lock on device, we can proceed
    else exit(1); // Device locked (by other instance ?)

    I'm not sure what other flags of flock I need to set.
    --
    Guillaume Dargaud
    http://www.gdargaud.net/



  9. Re: Checking for duplicate instances

    "Guillaume Dargaud"
    writes:
    > Is this a correct way to proceed ?
    >
    > fd = open(DevicePath, O_RDWR | O_NONBLOCK);
    > struct flock lock;
    > err = fcntl(fd, F_GETFL, &lock);
    > lock.l_type=F_WRLCK;
    > err = fcntl(fd, F_SETFL, &lock);
    > if (err==0) ; // No lock on device, we can proceed
    > else exit(1); // Device locked (by other instance ?)


    No. An uncompiled example of how to use fcntl locking would be

    struct flock lock;
    int fd, rc;

    fd = open("/path/to/file", O_RDWR);

    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = lock.l_len = 0;
    rc = fcntl(fd, F_SETLK, &lock);

    If the file is unlocked, rc will be 0 and the process will have
    acquired an exlusive lock on it. Otherwise, rc will be -1 and errno
    contain a 'suitable error code' (either EAGAIN or EACCESS).






+ Reply to Thread