Java Single Instance Application Example

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. If the program discovers that an instance of it is already running, then it should display a message indicating that it is already running and exit.

Contents

  • 1 Ada
  • 2 AutoHotkey
  • 3 BaCon
  • 4 Bash Shell
  • 5 BBC BASIC
  • 6 C
    • 6.1 POSIX with file lock
    • 6.2 POSIX with file creation
  • 7 C#
    • 7.1 Using a TCP Port
    • 7.2 Using a mutex
  • 8 C++
    • 8.1 Microsoft Windows
  • 9 Clojure
  • 10 D
    • 10.1 Unix Domain Socket
  • 11 Delphi
  • 12 Erlang
  • 13 FreeBASIC
  • 14 Go
    • 14.1 Port
    • 14.2 File
  • 15 Haskell
  • 16 Icon and Unicon
  • 17 Java
  • 18 Jsish
  • 19 Julia
  • 20 Kotlin
  • 21 Lasso
  • 22 Liberty BASIC
  • 23 M2000 Interpreter
  • 24 Mathematica / Wolfram Language
  • 25 Nim
    • 25.1 fcntl based
    • 25.2 Unix Domain Socket based
  • 26 OCaml
  • 27 Oz
  • 28 Perl
  • 29 Phix
  • 30 PicoLisp
    • 30.1 Calling 'killall'
    • 30.2 Using a mutex
  • 31 PowerShell
  • 32 PureBasic
  • 33 Python
    • 33.1 Linux (including cygwin) and Mac OSX Leopard
  • 34 Racket
  • 35 Raku
  • 36 REXX
  • 37 Ring
  • 38 Ruby
  • 39 Run BASIC
  • 40 Rust
  • 41 Scala
    • 41.1 Java Interoperability
  • 42 Sidef
  • 43 Swift
  • 44 Tcl
  • 45 TXR
    • 45.1 Microsoft Windows
  • 46 UNIX Shell
  • 47 Visual Basic
  • 48 Wren

Ada [edit]

The following solution tries to open a file for reading. If the file does not exist, a 'Name_Error' is raised. The exception handler creates that file, allows the program to perform its task, and, eventually, makes sure the file is deleted. If no exception is raised, the file exists, so another instance is running, and the program stops. It also stops if the wrong exception is raised, i.e., any exception other than 'Name_Error'.

          with          Ada.Text_IO;

procedure Single_Instance is

  package IO renames Ada.Text_IO;
Lock_File: IO.File_Type;
Lock_File_Name: String := "single_instance.magic_lock";

begin
begin
IO.Open (File => Lock_File, Mode=> IO.In_File, Name => Lock_File_Name);
IO.Close (Lock_File);
IO.Put_Line ( "I can't -- another instance of me is running ..." );
exception
when IO.Name_Error =>
IO.Put_Line ( "I can run!" );
IO.Create (File => Lock_File, Name => Lock_File_Name);
for I in 1 .. 10 loop
IO.Put (Integer'Image(I) );
delay 1.0; -- wait one second
end loop;
IO.Delete (Lock_File);
IO.New_Line;
IO.Put_Line ( "I am done!" );
end;
exception
when others => IO.Delete (Lock_File);
end Single_Instance;

Note that there is a race condition: If another instance tries to open the file for reading, before the first one has created it, then more than one instance will actually run.

AutoHotkey [edit]

AutoHotkey has a #SingleInstance command. If you run two scripts that don't have it at the same time, it alerts the user. #SingleInstance FORCE closes the older instance when a newer one is run, and #SingleInstance IGNORE does nothing when you try to open a new instance of an already-running script.

BaCon [edit]

Using advisory locks from libc.

PRAGMA INCLUDE <sys/file.h>
OPTION DEVICE O_NONBLOCK

 OPEN ME$ FOR DEVICE AS me

 IF flock(me, LOCK_EX | LOCK_NB) <> 0 THEN
PRINT "I am already running, exiting..."
END
ENDIF

 PRINT "Running this program, doing things..."
SLEEP 5000

 CLOSE DEVICE me

Bash Shell [edit]

Using flock, exits 0 if you got the lock, otherwise exits 1, below is a simplified example:


local fd=${2:-200}

 # create lock file
eval "exec $fd>/tmp/my_lock.lock"

 # acquire the lock, or fail
flock -nx $fd \
&& # do something if you got the lock \
|| # do something if you did not get the lock

There's a nice program called singleton that wraps this in an easy to use package : https://github.com/krezreb/singleton

BBC BASIC [edit]

Change 'UniqueLockName' to something more likely to be unique, such as a GUID.

          SYS "CreateMutex", 0, 1, "UniqueLockName" TO Mutex%
SYS "GetLastError" TO lerr%
IF lerr% = 183 THEN
SYS "CloseHandle", Mutex%
SYS "MessageBox", @hwnd%, "I am already running", 0, 0
QUIT
ENDIF

  SYS "ReleaseMutex", Mutex%
SYS "CloseHandle", Mutex%
END

C [edit]

POSIX with file lock [edit]

This solution opens ~/rosetta-code-lock and uses fcntl() to set a write lock on the file. Only one instance can set this lock. If fcntl() fails, this program assumes that another instance is running. This program always clears its lock when it terminates.

The user might use an interrupt or other signal to terminate the program. If so, the lock file survives, but the system still clears the lock. The user can run the program again.

Note that the underlying file system needs to support file locking; for example if ~/ directory is on a NFS mounted partition, success in a locking fcntl() call is not always meaningful.

          #include <fcntl.h>	/* fcntl, open */          
#include <stdlib.h> /* atexit, getenv, malloc */
#include <stdio.h> /* fputs, printf, puts, snprintf */
#include <string.h> /* memcpy */
#include <unistd.h> /* sleep, unlink */

/* Filename for only_one_instance() lock. */
#define INSTANCE_LOCK "rosetta-code-lock"

void
fail( const char *message)
{
perror (message) ;
exit ( 1 ) ;
}

/* Path to only_one_instance() lock. */
static char *ooi_path;

void
ooi_unlink( void )
{
unlink(ooi_path) ;
}

/* Exit if another instance of this program is running. */
void
only_one_instance( void )
{
struct flock fl;
size_t dirlen;
int fd;
char *dir;

  /*
* Place the lock in the home directory of this user;
* therefore we only check for other instances by the same
* user (and the user can trick us by changing HOME).
*/

dir = getenv ( "HOME" ) ;
if (dir == NULL || dir[ 0 ] != '/' ) {
fputs ( "Bad home directory.\n" , stderr) ;
exit ( 1 ) ;
}
dirlen = strlen (dir) ;

  ooi_path = malloc (dirlen + sizeof ( "/" INSTANCE_LOCK) ) ;
if (ooi_path == NULL)
fail( "malloc" ) ;
memcpy (ooi_path, dir, dirlen) ;
memcpy (ooi_path + dirlen, "/" INSTANCE_LOCK,
sizeof ( "/" INSTANCE_LOCK) ) ; /* copies '\0' */

  fd = open(ooi_path, O_RDWR | O_CREAT, 0600 ) ;
if (fd < 0 )
fail(ooi_path) ;

  fl.l_start = 0 ;
fl.l_len = 0 ;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
if (fcntl(fd, F_SETLK, &fl) < 0 ) {
fputs ( "Another instance of this program is running.\n" ,
stderr) ;
exit ( 1 ) ;
}

  /*
* Run unlink(ooi_path) when the program exits. The program
* always releases locks when it exits.
*/

atexit (ooi_unlink) ;
}

/*
* Demo for Rosetta Code.
* http://rosettacode.org/wiki/Determine_if_only_one_instance_is_running
*/

int
main( )
{
int i;

  only_one_instance( ) ;

  /* Play for 10 seconds. */
for (i = 10 ; i > 0 ; i-- ) {
printf ( "%d...%s" , i, i % 5 == 1 ? "\n" : " " ) ;
fflush (stdout) ;
sleep( 1 ) ;
}
puts ( "Fin!" ) ;
return 0 ;
}

POSIX with file creation [edit]

This solution opens a file with O_CREAT|O_EXCL. If the file already exists, this program assumes that another instance is running. This solution is not as good as file locking, because the program might terminate without deleting the file.

The program, when terminating, must be sure to unlink() the file. This example has unlink() at two places: at the end of main(), and at a SIGINT handler. If you interrupt the program, it will probably delete /tmp/MyUniqueName, but not if SIGINT wins a race before the program installs its handler. If you terminate the program with a different signal, then you will get stuck, because /tmp/MyUniqueName will still exist, preventing another execution of the program. One might add code to catch some other signals, but there is no way to catch SIGKILL!

This program uses a regular file, with open() and unlink(). There is an older version that uses a semaphore, with sem_open() and sem_unlink(). The switch from a semaphore to a regular file was easy, because the program never used the semaphore as a semaphore; it only checked the existence of a semaphore. If you get stuck, rm /tmp/MyUniqueName might be easier than deleting a semaphore.

          #include <fcntl.h>          
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* unistd for sleep */

void sigint_handler( int sig)
{
fprintf (stderr, "Caught signal %d.\n" , sig) ;
unlink( "/tmp/MyUniqueName" ) ;
/* exit() is not safe in a signal handler, use _exit() */
_exit( 1 ) ;
}

int main( )
{
struct sigaction act;
int myfd;

  myfd = open( "/tmp/MyUniqueName" , O_CREAT|O_EXCL) ;
if ( myfd < 0 )
{
fprintf (stderr, "I am already running!\n" ) ;
exit ( 1 ) ;
}
act.sa_handler = sigint_handler;
sigemptyset( &act.sa_mask ) ;
act.sa_flags = 0 ;
sigaction(SIGINT, &act, NULL) ;
/* here the real code of the app*/
sleep( 20 ) ;
/* end of the app */
unlink( "/tmp/MyUniqueName" ) ; close(myfd) ;
return 0 ;
}

C# [edit]

Using a TCP Port [edit]

          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." ) ;
}
}
}
}

Using a mutex [edit]


// Use this class in your process to guard against multiple instances
//
// This is valid for C# running on Windows, but not for C# with Linux.
//
using System ;
using System.Threading ;

/// <summary>
/// RunOnce should be instantiated in the calling processes main clause
/// (preferably using a "using" clause) and then calling process
/// should then check AlreadyRunning and do whatever is appropriate
/// </summary>
public class RunOnce : IDisposable
{
public RunOnce( string name )
{
m_name = name;
AlreadyRunning = false ;

  bool created_new = false ;

  m_mutex = new Mutex( false, m_name, out created_new ) ;

  AlreadyRunning = !created_new;
}

  ~RunOnce( )
{
DisposeImpl( false ) ;
}

  public bool AlreadyRunning
{
get { return m_already_running; }
private set { m_already_running = value ; }
}

  private void DisposeImpl( bool is_disposing )
{
GC. SuppressFinalize ( this ) ;

  if ( is_disposing )
{
m_mutex. Close ( ) ;
}
}

  #region IDisposable Members

  public void Dispose( )
{
DisposeImpl( true ) ;
}

 

0 Response to "Java Single Instance Application Example"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel