Determine if only one instance is running: Difference between revisions

From Rosetta Code
Content added Content deleted
(changed stdout to stderr)
(add Ruby)
Line 123: Line 123:


This is not a solution - one can run the same app by copying the code to another location. A solution may be a lock file or lock directory created by the first instance and hold while the first instance is running.
This is not a solution - one can run the same app by copying the code to another location. A solution may be a lock file or lock directory created by the first instance and hold while the first instance is running.

=={{header|Ruby}}==
Uses file locking on the program file
<lang ruby>def main
puts "first instance"
sleep 20
puts :done
end

if $0 == __FILE__
if DATA.flock(File::LOCK_EX)
main
else
die "another instance of this program is running"
end
end

__END__</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==

Revision as of 23:59, 6 July 2009

Task
Determine if only one instance is running
You are encouraged to solve this task according to the task description, using any language you may know.

This task is to determine if there is only one instance of an application running.

C

Works with: POSIX version .1-2001

Notes: this should work on every POSIX compliant system (you need to link with the POSIX thread pthread library).

It must be noted that if the program is interrupted and the sem_unlink is not executed, the semaphore will be still around preventing another execution of the program. So the program, when failing, must be sure to run the sem_unlink statement (e.g. doing it in a function that is passed to atexit and catching killing signals properly).

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <semaphore.h>
  3. include <unistd.h>
  4. include <fcntl.h>

/* unistd for sleep */

int main() {

  sem_t *mysem;
  
  mysem = sem_open("MyUniqueName", O_CREAT|O_EXCL);
  if ( mysem == NULL )
  {
     fprintf(stderr, "I am already running!\n");
     exit(1);
  }
  /* here the real code of the app*/
  sleep(20);
  /* end of the app */
  sem_unlink("MyUniqueName"); sem_close(mysem);

}</lang>


C++

Microsoft Windows

Works with: Windows version 2000 or later

This line needs to be near the top of the file (or in stdafx.h, if you use one.)

#include <afx.h>

You need a variable of type HANDLE with the same lifetime as your program. Perhaps as a member of your CWinApp object.

HANDLE mutex;

At the earliest possible point in your program, you need to initialize it and perform your check. "MyApp" should be a string unique to your application. See here for full details.

mutex = CreateMutex( NULL, TRUE, "MyApp" );
if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
     // There's another instance running.  What do you do?
}

Finally, near the end of your program, you need to close the mutex.

CloseHandle( mutex );

C#

<lang csharp>using System; using System.Net; using System.Net.Sockets;

class Program {

   static void Main(string[] args) {        
       try {
           TcpListener server = new TcpListener(IPAddress.Any, 12345);
           server.Start();
       } 
      
       catch (SocketException e) {
           if (e.SocketErrorCode == SocketError.AddressAlreadyInUse) {
               Console.Error.WriteLine("Already running.");
           }
       }
   }

}</lang>

Java

<lang java>import java.io.IOExeception; import java.net.InetAddress; import java.net.ServerSocket; import java.net.UnknownHostException;

public class SingletonApp { private static final int PORT = 12345; // random large port number private static ServerSocket s;

// static initializer { try { s = new ServerSocket(PORT, 10, InetAddress.getLocalHost()); } catch (UnknownHostException e) { // shouldn't happen for localhost } catch (IOException e) { // port taken, so app is already running System.exit(0); } } // main() and rest of application... }</lang>

Python

Linux (including cygwin) and Mac OSX Leopard

Works with: Python version 2.6

Must be run from an application, not the interpreter.

import __main__, os

def isOnlyInstance():
    # Determine if there are more than the current instance of the application
    # running at the current time. If not, return 0. If so, return 1.
    if not os.system('(( $(ps -ef | grep python | grep \'[' + \
    __main__.__file__[0] + ']' + __main__.__file__[1:len(__main__.__file__)] \
    + '\' | wc -l) > 1 ))'):
        return 0
    else:
        return 1

This is not a solution - one can run the same app by copying the code to another location. A solution may be a lock file or lock directory created by the first instance and hold while the first instance is running.

Ruby

Uses file locking on the program file <lang ruby>def main

 puts "first instance"
 sleep 20
 puts :done

end

if $0 == __FILE__

 if DATA.flock(File::LOCK_EX)
   main
 else
   die "another instance of this program is running"
 end

end

__END__</lang>

Tcl

Translation of: Java


Works with: Tcl version 8.6

<lang Tcl>set APP_SPECIFIC_PORT_NUMBER 12345 try {

   socket -server closePort -myaddr localhost $APP_SPECIFIC_PORT_NUMBER
   proc closePort {chan add port} {close $chan}

} trap {POSIX EADDRINUSE} {} {

   # Generate a nice error message
   puts stderr "Application $::argv0 already running?"
   exit

}</lang>

Visual Basic

Works with: Visual Basic version 6
 Dim onlyInstance as Boolean
 onlyInstance = not App.PrevInstance