How to know there are multiple instances inside application itself,not through ssh

hi,

As you know, in Windows Programming, in WinMain method you will give n argument which you can know if this is another instance of the application or just the fresh execution.
How this functionality can be achieved in Linux application? Most of suggestions i have seen here in threads are done through ssh and shell scripting not inside application itself.

Regards,
Behzad

Probably that should be controlled and/or configured via master application, which will take care of whether to spawn a new instance of application or not based on load and other parameters.

With that, master application has the knowledge of all its instances it has spawned and if required can pass the nth instance info to a specific instance.

Remember, this is Windows. Just because they designed functionality doesn't mean it works. From MSDN:

hPrevInstance
    [in] Handle to the previous instance of the application. This parameter is always NULL.

Probably much the same as you must do in Windows, or for that matter, in those shell threads: Create a lockfile of some sort.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>

// Have this called at exit
void cleanup(void)
{
        unlink("pidfile");
}

int get_lockfile(void)
{
        char buf[64];
        int len;
        // O_EXCL tells it to fail if the file already exists.
        int fd=open("pidfile", O_RDWR|O_CREAT|O_EXCL);
        if(fd < 0)
                return(-1);

        fprintf(stderr, "PID %d has the lockfile.\n", getpid());
        // Write the PID to the file
        len=sprintf(buf, "%d", getpid());
        write(fd, len, buf);
        close(fd);

        // Have cleanup() called automatically when main() returns
        atexit(cleanup);
        return(0);
}

int main(void)
{
        if(get_lockfile() < 0)
        {
                fprintf(stderr, "PID %d couldn't get lockfile\n", getpid());
                return(1);
        }

        sleep(10);
        fprintf(stderr, "PID %d releasing lockfile\n", getpid());
        return(0);
}

Depending on what system you're on, there could be lots of other ways of doing it too. Cooperative locking would be one, just try to make a cooperative lock on your own executable file...

When you startup, you could traverse through the process list to see if there is another process with the same name. For that to happen, you need to also check if your process is running as the original name. This ofcourse is limited to those OS'es that have the /proc available.

Since you are familiar with the Windows Programming, you could use something similar to named events. See this link for events in Windows and Linux - Port Windows IPC apps to Linux, Part 2: Semaphores and events

On Solaris, you can also do an FUSER variant of the utssys system call on the executable and see how many processes have the file open for execution. Look at sys/utssys.h and sys/syscall.h and the source code for the "fuser" utility at OpenSolaris.org to see how you can do that.

Or your can just fork off a subprocess using system() to run "fuser" and parse the output. That could also work on Linux by using "lsof".

I do not recommend replicating what "lsof" does in your own source code. Last time I looked at that source code, Linux did not have the equivalent of the Solaris utssys/fuser system call, so instead of a single system call "lsof" was forced to walk the entire /proc process tree looking for results. That added up to a lot of source code. Replicating that functionality in your app would add a lot of complexity along with dependencies on how Linux implements things in /proc, something you probably don't want to do.

Suggestion:

Create a named semaphore with sem_open. This has one disadvantage - if the program crashes the semaphore persists. If you perceive this as a problem for you then
create a program special option (like -f) to force the program to call sem_unlink() before it does anything else. The option is not provided under normal operation.

  1. sem_open() - then check the semaphore setting to see if it is less than the maximum limit you want to impose.
  2. if it is at max, then exit, (Windows does something like this) else increment the sempahore.
  3. register an atexit function:
    decrement the semaphore
    if the semaphore is now zero, call sym_unlink()
  4. run the rest of your code
  5. exit (#3 handles the sempahore for you.)