Determine if only one instance is running

From Rosetta Code
Jump to: navigation, search
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

[edit] Ada

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, or any other exception, the program stops immediately.

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.

[edit] AutoHotkey

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.

[edit] BBC BASIC

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

[edit] C

[edit] POSIX with file lock

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.

Library: POSIX
#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;
}

[edit] POSIX with file creation

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.

Library: POSIX
#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;
}

[edit] C++

[edit] 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 );

[edit] C#

[edit] Using a TCP Port

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

[edit] Using a mutex

 
// Use this class in your process to guard against multiple instances
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 );
}
 
#endregion
 
private string m_name;
private bool m_already_running;
private Mutex m_mutex;
}
 
class Program
{
// Example code to use this
static void Main( string[] args )
{
using ( RunOnce ro = new RunOnce( "App Name" ) )
{
if ( ro.AlreadyRunning )
{
Console.WriteLine( "Already running" );
return;
}
 
// Program logic
}
}
}

[edit] Clojure

Translation of: Java
(import (java.net ServerSocket InetAddress))
 
(def *port* 12345) ; random large port number
(try (new ServerSocket *port* 10 (. InetAddress getLocalHost))
(catch IOException e (System/exit 0))) ; port taken, so app is already running

[edit] Delphi

program OneInstance;
 
{$APPTYPE CONSOLE}
 
uses SysUtils, Windows;
 
var
FMutex: THandle;
begin
FMutex := CreateMutex(nil, True, 'OneInstanceMutex');
if FMutex = 0 then
RaiseLastOSError
else
begin
try
if GetLastError = ERROR_ALREADY_EXISTS then
Writeln('Program already running. Closing...')
else
begin
// do stuff ...
Readln;
end;
finally
CloseHandle(FMutex);
end;
end;
end.

[edit] Erlang

From the Erlang shell, or in a program, register the application process. It this works the process is the only one.

Output:
7> erlang:register( aname, erlang:self() ).          
true
8> erlang:register( aname, erlang:self() ).
** exception error: bad argument
     in function  register/2
        called as register(aname,<0.42.0>)

[edit] Go

Solution using O_CREATE|O_EXCL, and with messages and a 10 second sleep to let you test it.

package main
 
import (
"fmt"
"os"
"strconv"
"strings"
"time"
)
 
// The path to the lock file should be an absolute path starting from the root.
// (If you wish to prevent the same program running in different directories, that is.)
const lfn = "/tmp/rclock"
 
func main() {
lf, err := os.OpenFile(lfn, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
if err == nil {
// good
// 10 digit pid seems to be a standard for lock files
fmt.Fprintf(lf, "%10d", os.Getpid())
lf.Close()
defer os.Remove(lfn)
} else {
// problem
fmt.Println(err)
// dig deeper
lf, err = os.Open(lfn)
if err != nil {
return
}
defer lf.Close()
fmt.Println("inspecting lock file...")
b10 := make([]byte, 10)
_, err = lf.Read(b10)
if err != nil {
fmt.Println(err)
return
}
pid, err := strconv.Atoi(strings.TrimSpace(string(b10)))
if err != nil {
fmt.Println(err)
return
}
fmt.Println("lock file created by pid", pid)
return
}
fmt.Println(os.Getpid(), "running...")
time.Sleep(1e10)
}

[edit] Haskell

Simple implementation using a lock file. Two threads are launched, but the second cannot start because the first has created a lock file which is deleted when it has finished.

import Control.Concurrent
import System.Directory (doesFileExist, getAppUserDataDirectory,
removeFile)
import System.IO (withFile, Handle, IOMode(WriteMode), hPutStr)
 
oneInstance :: IO ()
oneInstance = do
-- check if file "$HOME/.myapp.lock" exists
user <- getAppUserDataDirectory "myapp.lock"
locked <- doesFileExist user
if locked
then print "There is already one instance of this program running."
else do
t <- myThreadId
-- this is the entry point to the main program:
-- withFile creates a file, then calls a function,
-- then closes the file
withFile user WriteMode (do_program t)
-- remove the lock when we're done
removeFile user
 
do_program :: ThreadId -> Handle -> IO ()
do_program t h = do
let s = "Locked by thread: " ++ show t
-- print what thread has acquired the lock
putStrLn s
-- write the same message to the file, to show that the
-- thread "owns" the file
hPutStr h s
-- wait for one second
threadDelay 1000000
 
main :: IO ()
main = do
-- launch the first thread, which will create the lock file
forkIO oneInstance
-- wait for half a second
threadDelay 500000
-- launch the second thread, which will find the lock file and
-- thus will exit immediately
forkIO oneInstance
return ()

[edit] Icon and Unicon

The following only works in Unicon. The program uses a socket as a flag.

procedure main(A)
if not open(":"||54321,"na") then stop("Already running")
repeat {} # busy loop
end

Sample run:

->self &
[1] 15358
->self
Already running
->

[edit] 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...
}


[edit] Lasso

#!/usr/bin/lasso9
 
local(lockfile = file('/tmp/myprocess.lockfile'))
 
if(#lockfile -> exists) => {
stdoutnl('Error: App is running as of ' + #lockfile -> readstring)
abort
}
 
handle => {
#lockfile -> delete
}
 
stdoutnl('Starting execution')
 
#lockfile -> doWithClose => {
#lockfile -> writebytes(bytes(date))
}
 
sleep(10000)
 
stdoutnl('Execution done')

Output Window 1:

$./rosetta 
Starting execution
Execution done

Output Window 2:

$./rosetta 
Error: App is running as of 2013-11-27 08:42:45

[edit] Liberty BASIC

'Create a Mutex to prevent more than one instance from being open at a single time.
CallDLL #kernel32, "CreateMutexA", 0 as Long, 1 as Long, "Global\My Program" as ptr, mutex as ulong
CallDLL #kernel32, "GetLastError", LastError as Long
 
if LastError = 183 then 'Error returned when a Mutex already exists
'Close the handle if the mutex already exists
calldll #kernel32, "CloseHandle", mutex as ulong, ret as ulong
notice "An instance of My Program is currently running!"
end
end if
 
'Release the Mutex/ Close the handle prior to ending the program
'Comment out these lines to allow the program to remain active to test for the mutex's presence
calldll #kernel32, "ReleaseMutex", mutex as ulong, ret as ulong
calldll #kernel32, "CloseHandle", mutex as ulong, ret as ulong
end

[edit] Mathematica

$Epilog is the action performed upon session exit. Running the following code before any other code will prevent 2 instances from concurrent execution.

$Epilog := Print["Another instance is running "]; 
If[Attributes[Global`Mutex] == {Protected},
Exit[],
Global`Mutex[x_] := Locked; Protect[Global`Mutex];
]

[edit] OCaml

Replicates the C example, with the library ocaml-sem.

open Sem
 
let () =
let oflags = [Unix.O_CREAT;
Unix.O_EXCL] in
let sem = sem_open "MyUniqueName" ~oflags () in
(* here the real code of the app *)
Unix.sleep 20;
(* end of the app *)
sem_unlink "MyUniqueName";
sem_close sem

The standard library of OCaml also provides a Mutex module.

[edit] Oz

functor
import Application Open System
define
fun {IsAlreadyRunning}
try
S = {New Open.socket init}
in
{S bind(takePort:12345)}
false
catch system(os(os "bind" ...) ...) then
true
end
end
 
if {IsAlreadyRunning} then
{System.showInfo "Exiting because already running."}
{Application.exit 1}
end
{System.showInfo "Press enter to exit."}
{{New Open.file init(name:stdin)} read(list:_ size:1)}
{Application.exit 0}
end

[edit] Perl

The INIT block is runned just before the Perl runtime begins execution. See perlmod

Then it tries to get a lock to its own file, from where the script was called.

use Fcntl ':flock';
 
INIT
{
die "Not able to open $0\n" unless (open ME, $0);
die "I'm already running !!\n" unless(flock ME, LOCK_EX|LOCK_NB);
}
 
sleep 60; # then your code goes here

[edit] Perl 6

An old-school Unix solution, none the worse for the wear:

my $name = $*PROGRAM_NAME;
my $pid = $*PID;
 
my $lockdir = "/tmp";
my $lockfile = "$lockdir/$name.pid";
my $lockpid = "$lockfile$pid";
my $havelock = False;
 
END {
unlink $lockfile if $havelock;
try unlink $lockpid;
}
 
my $pidfile = open "$lockpid", :w or die "Can't create $lockpid: $!";
$pidfile.say($pid);
$pidfile.close;
 
if try link($lockpid, $lockfile) {
$havelock = True;
}
else {
shell "kill -CONT `cat $lockfile` || rm $lockfile";
if try link($lockpid, $lockfile) {
$havelock = True;
}
else {
die "You can't run right now!";
}
}
note "Got lock!";
unlink $lockpid;

[edit] PicoLisp

[edit] Calling 'killall'

One possibility is to send a zero-signal with 'killall', and check the return value. This is useful if each application is started by a hash-bang script (the first line is e.g. "#!/usr/bin/picolisp /usr/lib/picolisp/lib.l"). In that way, each application has its own name which can be passed to 'killall'.

$ cat myScript
#!/usr/bin/picolisp /usr/lib/picolisp/lib.l

(wait 120000)
(bye)
$ ./myScript &  # Start in the background
[1] 26438
$ pil +
: (call "killall" "-0" "-q" "myScript")
-> T

[edit] Using a mutex

Another possibility is to 'acquire' a mutex on program start, and never release it.

: (acquire "running1")
-> 30817 # A successful call returns the PID

A second application trying to acquire the same mutex would receive 'NIL'

[edit] PureBasic

#MyApp="MyLittleApp"
Mutex=CreateMutex_(0,1,#MyApp)
If GetLastError_()=#ERROR_ALREADY_EXISTS
MessageRequester(#MyApp,"One instance is already started.")
End
EndIf
 
; Main code executes here
 
ReleaseMutex_(Mutex)
End

[edit] Python

[edit] 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.
return os.system("(( $(ps -ef | grep python | grep '[" +
__main__.__file__[0] + "]" + __main__.__file__[1:] +
"' | wc -l) > 1 ))") != 0

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.

[edit] Racket

Translation of: Java
 
#lang racket
(define *port* 12345) ; random large port number
(define listener-handler
(with-handlers ([exn? (λ(e) (printf "Already running, bye.\n") (exit))])
(tcp-listen *port*)))
(printf "Working...\n")
(sleep 10)
 

[edit] Ruby

Uses file locking on the program file

def main
puts "first instance"
sleep 20
puts :done
end
 
if $0 == __FILE__
if File.new(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
main
else
raise "another instance of this program is running"
end
end
 
__END__

[edit] Run BASIC

if instr(shell$("tasklist"),"rbp.exe") <> 0 then print "Task is Running"

[edit] Tcl

Translation of: Java
Works with: Tcl version 8.6
package require Tcl 8.6
try {
# Pick a port number based on the name of the main script executing
socket -server {apply {{chan args} {close $chan}}} -myaddr localhost \
[expr {1024 + [zlib crc32 [file normalize $::argv0]] % 30000}]
} trap {POSIX EADDRINUSE} {} {
# Generate a nice error message
puts stderr "Application $::argv0 already running?"
exit 1
}

[edit] UNIX Shell

Works with: Bourne Shell
Works with: Bourne Again SHell
 
# (c) Copyright 2005 Mark Hobley
#
# This is free software. This file can be redistributed or modified
# under the terms of version 1.2 of the GNU Free Documentation Licence
# as published by the Free Software Foundation.
#
 
singleinstance ()
{
if [ -d $SRUNDIR ] ; then
if [ -w $SRUNDIR ] ; then
if [ -d $SRUNDIR/$APPNAME ] ; then
echo "Process Already Running" >& 2
return 221
else
mkdir $SRUNDIR/$APPNAME
if [ "$?" -ne 0 ] ; then
if [ -d $SRUNDIR/$APPNAME ] ; then
echo "Process Already Running" >& 2
return 221
else
echo "Unexpected Error" >& 2
return 239
fi
fi
return 0 ; # This is a unique instance
fi
else
echo "Permission Denied" >& 2
return 210
fi
else
echo "Missing Directory" >& 2
return 199
fi
}
 

[edit] Visual Basic

Works with: Visual Basic version 4
Dim onlyInstance as Boolean
onlyInstance = not App.PrevInstance
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox