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.

Contents

[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] 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).

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#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);
}


[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#

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] 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] 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] 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] 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 onw 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
$ ./dbg
: (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] 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] 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] Visual Basic

Works with: Visual Basic version 6

Dim onlyInstance as Boolean
onlyInstance = not App.PrevInstance
Personal tools
Support