Determine if only one instance is running: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: added syntax colouring, marked p2js incompatible) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 7: | Line 7: | ||
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'. |
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'. |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
procedure Single_Instance is |
procedure Single_Instance is |
||
Line 34: | Line 34: | ||
exception |
exception |
||
when others => IO.Delete(Lock_File); |
when others => IO.Delete(Lock_File); |
||
end Single_Instance;</ |
end Single_Instance;</syntaxhighlight> |
||
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. |
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. |
||
Line 43: | Line 43: | ||
=={{header|BaCon}}== |
=={{header|BaCon}}== |
||
Using advisory locks from libc. |
Using advisory locks from libc. |
||
< |
<syntaxhighlight lang="bacon">PRAGMA INCLUDE <sys/file.h> |
||
OPTION DEVICE O_NONBLOCK |
OPTION DEVICE O_NONBLOCK |
||
Line 56: | Line 56: | ||
SLEEP 5000 |
SLEEP 5000 |
||
CLOSE DEVICE me</ |
CLOSE DEVICE me</syntaxhighlight> |
||
=={{header|Bash Shell}}== |
=={{header|Bash Shell}}== |
||
Line 62: | Line 62: | ||
Using flock, exits 0 if you got the lock, otherwise exits 1, below is a simplified example: |
Using flock, exits 0 if you got the lock, otherwise exits 1, below is a simplified example: |
||
< |
<syntaxhighlight lang="bbcbasic"> |
||
local fd=${2:-200} |
local fd=${2:-200} |
||
Line 72: | Line 72: | ||
&& # do something if you got the lock \ |
&& # do something if you got the lock \ |
||
|| # do something if you did not get the lock |
|| # do something if you did not get the lock |
||
</syntaxhighlight> |
|||
</lang> |
|||
There's a nice program called singleton that wraps this in an easy to use package : https://github.com/krezreb/singleton |
There's a nice program called singleton that wraps this in an easy to use package : https://github.com/krezreb/singleton |
||
Line 79: | Line 79: | ||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
Change 'UniqueLockName' to something more likely to be unique, such as a GUID. |
Change 'UniqueLockName' to something more likely to be unique, such as a GUID. |
||
< |
<syntaxhighlight lang="bbcbasic"> SYS "CreateMutex", 0, 1, "UniqueLockName" TO Mutex% |
||
SYS "GetLastError" TO lerr% |
SYS "GetLastError" TO lerr% |
||
IF lerr% = 183 THEN |
IF lerr% = 183 THEN |
||
Line 89: | Line 89: | ||
SYS "ReleaseMutex", Mutex% |
SYS "ReleaseMutex", Mutex% |
||
SYS "CloseHandle", Mutex% |
SYS "CloseHandle", Mutex% |
||
END</ |
END</syntaxhighlight> |
||
=={{header|C}}== |
=={{header|C}}== |
||
Line 100: | Line 100: | ||
{{libheader|POSIX}} |
{{libheader|POSIX}} |
||
< |
<syntaxhighlight lang="c">#include <fcntl.h> /* fcntl, open */ |
||
#include <stdlib.h> /* atexit, getenv, malloc */ |
#include <stdlib.h> /* atexit, getenv, malloc */ |
||
#include <stdio.h> /* fputs, printf, puts, snprintf */ |
#include <stdio.h> /* fputs, printf, puts, snprintf */ |
||
Line 193: | Line 193: | ||
puts("Fin!"); |
puts("Fin!"); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=== POSIX with file creation === |
=== POSIX with file creation === |
||
Line 203: | Line 203: | ||
{{libheader|POSIX}} |
{{libheader|POSIX}} |
||
< |
<syntaxhighlight lang="c">#include <fcntl.h> |
||
#include <signal.h> |
#include <signal.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 238: | Line 238: | ||
unlink("/tmp/MyUniqueName"); close(myfd); |
unlink("/tmp/MyUniqueName"); close(myfd); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
===Using a TCP Port=== |
===Using a TCP Port=== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Net; |
using System.Net; |
||
using System.Net.Sockets; |
using System.Net.Sockets; |
||
Line 260: | Line 260: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Using a mutex=== |
===Using a mutex=== |
||
< |
<syntaxhighlight lang="csharp"> |
||
// Use this class in your process to guard against multiple instances |
// Use this class in your process to guard against multiple instances |
||
// |
// |
||
Line 341: | Line 341: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 347: | Line 347: | ||
{{works with|Windows|2000 or later}} |
{{works with|Windows|2000 or later}} |
||
This line needs to be near the top of the file (or in stdafx.h, if you use one.) |
This line needs to be near the top of the file (or in stdafx.h, if you use one.) |
||
<lang |
<syntaxhighlight lang="cpp">#include <afx.h></syntaxhighlight> |
||
You need a variable of type HANDLE with the same lifetime as your program. Perhaps as a member of your CWinApp object. |
You need a variable of type HANDLE with the same lifetime as your program. Perhaps as a member of your CWinApp object. |
||
<lang |
<syntaxhighlight lang="cpp">HANDLE mutex;</syntaxhighlight> |
||
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 [http://msdn2.microsoft.com/en-us/library/ms682411.aspx here] for full details. |
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 [http://msdn2.microsoft.com/en-us/library/ms682411.aspx here] for full details. |
||
< |
<syntaxhighlight lang="cpp">mutex = CreateMutex( NULL, TRUE, "MyApp" ); |
||
if ( GetLastError() == ERROR_ALREADY_EXISTS ) |
if ( GetLastError() == ERROR_ALREADY_EXISTS ) |
||
{ |
{ |
||
// There's another instance running. What do you do? |
// There's another instance running. What do you do? |
||
}</ |
}</syntaxhighlight> |
||
Finally, near the end of your program, you need to close the mutex. |
Finally, near the end of your program, you need to close the mutex. |
||
<lang |
<syntaxhighlight lang="cpp">CloseHandle( mutex );</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="clojure">(import (java.net ServerSocket InetAddress)) |
||
(def *port* 12345) ; random large port number |
(def *port* 12345) ; random large port number |
||
(try (new ServerSocket *port* 10 (. InetAddress getLocalHost)) |
(try (new ServerSocket *port* 10 (. InetAddress getLocalHost)) |
||
(catch IOException e (System/exit 0))) ; port taken, so app is already running </ |
(catch IOException e (System/exit 0))) ; port taken, so app is already running </syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
Line 380: | Line 380: | ||
All we need is to generate a unique name for our program and pass it as the address when calling bind(). The trick is that instead of specifying a file path as the address, we pass a null byte followed by the name of our choosing (e.g. "\0my-unique-name"). The initial null byte is what distinguishes abstract socket names from conventional Unix domain socket path names, which consist of a string of one or more non-null bytes terminated by a null byte. |
All we need is to generate a unique name for our program and pass it as the address when calling bind(). The trick is that instead of specifying a file path as the address, we pass a null byte followed by the name of our choosing (e.g. "\0my-unique-name"). The initial null byte is what distinguishes abstract socket names from conventional Unix domain socket path names, which consist of a string of one or more non-null bytes terminated by a null byte. |
||
Read more here: [https://blog.petrzemek.net/2017/07/24/ensuring-that-a-linux-program-is-running-at-most-once-by-using-abstract-sockets/] |
Read more here: [https://blog.petrzemek.net/2017/07/24/ensuring-that-a-linux-program-is-running-at-most-once-by-using-abstract-sockets/] |
||
<syntaxhighlight lang="d"> |
|||
<lang d> |
|||
bool is_unique_instance() |
bool is_unique_instance() |
||
{ |
{ |
||
Line 401: | Line 401: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">program OneInstance; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 430: | Line 430: | ||
end; |
end; |
||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Line 446: | Line 446: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">Shell("tasklist > temp.txt") |
||
Dim linea As String |
Dim linea As String |
||
Line 456: | Line 456: | ||
Close #1 |
Close #1 |
||
Shell("del temp.txt") |
Shell("del temp.txt") |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
Line 463: | Line 463: | ||
Recommended over file based solutions. It has the advantage that the port is always released |
Recommended over file based solutions. It has the advantage that the port is always released |
||
when the process ends. |
when the process ends. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 481: | Line 481: | ||
fmt.Println("single instance started") |
fmt.Println("single instance started") |
||
time.Sleep(10 * time.Second) |
time.Sleep(10 * time.Second) |
||
}</ |
}</syntaxhighlight> |
||
===File=== |
===File=== |
||
Solution using O_CREATE|O_EXCL. This solution has the problem that if anything terminates the |
Solution using O_CREATE|O_EXCL. This solution has the problem that if anything terminates the |
||
program early, the lock file remains. |
program early, the lock file remains. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 508: | Line 508: | ||
time.Sleep(10 * time.Second) |
time.Sleep(10 * time.Second) |
||
os.Remove(lfn) |
os.Remove(lfn) |
||
}</ |
}</syntaxhighlight> |
||
Here's a fluffier version that stores the PID in the lock file to provide better messages. |
Here's a fluffier version that stores the PID in the lock file to provide better messages. |
||
It has the same problem of the lock file remaining if anything terminates the program early. |
It has the same problem of the lock file remaining if anything terminates the program early. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 559: | Line 559: | ||
fmt.Println(os.Getpid(), "running...") |
fmt.Println(os.Getpid(), "running...") |
||
time.Sleep(1e10) |
time.Sleep(1e10) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Haskell}}== |
=={{header|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. |
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. |
||
< |
<syntaxhighlight lang="haskell">import Control.Concurrent |
||
import System.Directory (doesFileExist, getAppUserDataDirectory, |
import System.Directory (doesFileExist, getAppUserDataDirectory, |
||
removeFile) |
removeFile) |
||
Line 604: | Line 604: | ||
-- thus will exit immediately |
-- thus will exit immediately |
||
forkIO oneInstance |
forkIO oneInstance |
||
return ()</ |
return ()</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 610: | Line 610: | ||
The following only works in Unicon. The program uses a socket as a flag. |
The following only works in Unicon. The program uses a socket as a flag. |
||
< |
<syntaxhighlight lang="unicon">procedure main(A) |
||
if not open(":"||54321,"na") then stop("Already running") |
if not open(":"||54321,"na") then stop("Already running") |
||
repeat {} # busy loop |
repeat {} # busy loop |
||
end</ |
end</syntaxhighlight> |
||
Sample run: |
Sample run: |
||
Line 626: | Line 626: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang="java">import java.io.IOException; |
||
import java.net.InetAddress; |
import java.net.InetAddress; |
||
import java.net.ServerSocket; |
import java.net.ServerSocket; |
||
Line 660: | Line 660: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Jsish}}== |
=={{header|Jsish}}== |
||
Using a socket on a fixed port number. |
Using a socket on a fixed port number. |
||
< |
<syntaxhighlight lang="javascript">/* Determine if only one instance, in Jsish */ |
||
var sock; |
var sock; |
||
Line 675: | Line 675: | ||
puts('Applicaion already running'); |
puts('Applicaion already running'); |
||
exit(1); |
exit(1); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 693: | Line 693: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{trans|Java}}< |
{{trans|Java}}<syntaxhighlight lang="julia"> |
||
using Sockets |
using Sockets |
||
Line 711: | Line 711: | ||
canopen() |
canopen() |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
import java.io.IOException |
import java.io.IOException |
||
Line 749: | Line 749: | ||
SingleInstance.close() |
SingleInstance.close() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 764: | Line 764: | ||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
< |
<syntaxhighlight lang="lasso">#!/usr/bin/lasso9 |
||
local(lockfile = file('/tmp/myprocess.lockfile')) |
local(lockfile = file('/tmp/myprocess.lockfile')) |
||
Line 785: | Line 785: | ||
sleep(10000) |
sleep(10000) |
||
stdoutnl('Execution done')</ |
stdoutnl('Execution done')</syntaxhighlight> |
||
Output Window 1: |
Output Window 1: |
||
Line 799: | Line 799: | ||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
< |
<syntaxhighlight lang="lb">'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, "CreateMutexA", 0 as Long, 1 as Long, "Global\My Program" as ptr, mutex as ulong |
||
CallDLL #kernel32, "GetLastError", LastError as Long |
CallDLL #kernel32, "GetLastError", LastError as Long |
||
Line 814: | Line 814: | ||
calldll #kernel32, "ReleaseMutex", mutex as ulong, ret as ulong |
calldll #kernel32, "ReleaseMutex", mutex as ulong, ret as ulong |
||
calldll #kernel32, "CloseHandle", mutex as ulong, ret as ulong |
calldll #kernel32, "CloseHandle", mutex as ulong, ret as ulong |
||
end</ |
end</syntaxhighlight> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
We can lock a file in user folder. Only one instance can lock a file. |
We can lock a file in user folder. Only one instance can lock a file. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Checkit { |
Module Checkit { |
||
Try { |
Try { |
||
Line 828: | Line 828: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
$Epilog is the action performed upon session exit. |
$Epilog is the action performed upon session exit. |
||
Running the following code before any other code will prevent 2 instances from concurrent execution. |
Running the following code before any other code will prevent 2 instances from concurrent execution. |
||
< |
<syntaxhighlight lang="mathematica">$Epilog := Print["Another instance is running "]; |
||
If[Attributes[Global`Mutex] == {Protected}, |
If[Attributes[Global`Mutex] == {Protected}, |
||
Exit[], |
Exit[], |
||
Global`Mutex[x_] := Locked; Protect[Global`Mutex]; |
Global`Mutex[x_] := Locked; Protect[Global`Mutex]; |
||
]</ |
]</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
===fcntl based=== |
===fcntl based=== |
||
< |
<syntaxhighlight lang="nim">import os, posix |
||
let fn = getHomeDir() & "rosetta-code-lock" |
let fn = getHomeDir() & "rosetta-code-lock" |
||
Line 860: | Line 860: | ||
echo i |
echo i |
||
sleep 1000 |
sleep 1000 |
||
echo "Fin!"</ |
echo "Fin!"</syntaxhighlight> |
||
===Unix Domain Socket based=== |
===Unix Domain Socket based=== |
||
< |
<syntaxhighlight lang="nim">import options, os |
||
from net import newSocket, bindUnix |
from net import newSocket, bindUnix |
||
from nativesockets import AF_UNIX, SOCK_DGRAM, IPPROTO_IP |
from nativesockets import AF_UNIX, SOCK_DGRAM, IPPROTO_IP |
||
Line 898: | Line 898: | ||
server() |
server() |
||
else: |
else: |
||
client()</ |
client()</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Replicates the '''C''' example, with the library [http://ocaml-sem.sourceforge.net/ ocaml-sem]. |
Replicates the '''C''' example, with the library [http://ocaml-sem.sourceforge.net/ ocaml-sem]. |
||
< |
<syntaxhighlight lang="ocaml">open Sem |
||
let () = |
let () = |
||
Line 912: | Line 912: | ||
(* end of the app *) |
(* end of the app *) |
||
sem_unlink "MyUniqueName"; |
sem_unlink "MyUniqueName"; |
||
sem_close sem</ |
sem_close sem</syntaxhighlight> |
||
The standard library of OCaml also provides a [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Mutex.html Mutex] module. |
The standard library of OCaml also provides a [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Mutex.html Mutex] module. |
||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
< |
<syntaxhighlight lang="oz">functor |
||
import Application Open System |
import Application Open System |
||
define |
define |
||
Line 938: | Line 938: | ||
{{New Open.file init(name:stdin)} read(list:_ size:1)} |
{{New Open.file init(name:stdin)} read(list:_ size:1)} |
||
{Application.exit 0} |
{Application.exit 0} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Line 944: | Line 944: | ||
Then it tries to get a lock to its own file, from where the script was called. |
Then it tries to get a lock to its own file, from where the script was called. |
||
< |
<syntaxhighlight lang="perl">use Fcntl ':flock'; |
||
INIT |
INIT |
||
Line 952: | Line 952: | ||
} |
} |
||
sleep 60; # then your code goes here</ |
sleep 60; # then your code goes here</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{libheader|Phix/pGUI}} |
{{libheader|Phix/pGUI}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Single_instance.exw</span> |
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Single_instance.exw</span> |
||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> |
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> |
||
Line 977: | Line 977: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Line 992: | Line 992: | ||
<pre>$ ./myScript & # Start in the background |
<pre>$ ./myScript & # Start in the background |
||
[1] 26438</pre> |
[1] 26438</pre> |
||
< |
<syntaxhighlight lang="picolisp">$ pil + |
||
: (call "killall" "-0" "-q" "myScript") |
: (call "killall" "-0" "-q" "myScript") |
||
-> T</ |
-> T</syntaxhighlight> |
||
===Using a mutex=== |
===Using a mutex=== |
||
Another possibility is to 'acquire' a mutex on program start, and never release |
Another possibility is to 'acquire' a mutex on program start, and never release |
||
it. |
it. |
||
< |
<syntaxhighlight lang="picolisp">: (acquire "running1") |
||
-> 30817 # A successful call returns the PID</ |
-> 30817 # A successful call returns the PID</syntaxhighlight> |
||
A second application trying to acquire the same mutex would receive 'NIL' |
A second application trying to acquire the same mutex would receive 'NIL' |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
if (Get-Process -Name "notepad" -ErrorAction SilentlyContinue) |
if (Get-Process -Name "notepad" -ErrorAction SilentlyContinue) |
||
{ |
{ |
||
Line 1,013: | Line 1,013: | ||
Start-Process -FilePath C:\Windows\notepad.exe |
Start-Process -FilePath C:\Windows\notepad.exe |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
No output because notepad.exe was not running, so it was started. |
No output because notepad.exe was not running, so it was started. |
||
{{Out}} |
{{Out}} |
||
Line 1,019: | Line 1,019: | ||
</pre> |
</pre> |
||
Run it again. |
Run it again. |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
if (Get-Process -Name "notepad" -ErrorAction SilentlyContinue) |
if (Get-Process -Name "notepad" -ErrorAction SilentlyContinue) |
||
{ |
{ |
||
Line 1,028: | Line 1,028: | ||
Start-Process -FilePath C:\Windows\notepad.exe |
Start-Process -FilePath C:\Windows\notepad.exe |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Since it is running a warning message is output. |
Since it is running a warning message is output. |
||
{{Out}} |
{{Out}} |
||
Line 1,036: | Line 1,036: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">#MyApp="MyLittleApp" |
||
Mutex=CreateMutex_(0,1,#MyApp) |
Mutex=CreateMutex_(0,1,#MyApp) |
||
If GetLastError_()=#ERROR_ALREADY_EXISTS |
If GetLastError_()=#ERROR_ALREADY_EXISTS |
||
Line 1,046: | Line 1,046: | ||
ReleaseMutex_(Mutex) |
ReleaseMutex_(Mutex) |
||
End</ |
End</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 1,054: | Line 1,054: | ||
Must be run from an application, not the interpreter. |
Must be run from an application, not the interpreter. |
||
< |
<syntaxhighlight lang="python">import __main__, os |
||
def isOnlyInstance(): |
def isOnlyInstance(): |
||
Line 1,061: | Line 1,061: | ||
return os.system("(( $(ps -ef | grep python | grep '[" + |
return os.system("(( $(ps -ef | grep python | grep '[" + |
||
__main__.__file__[0] + "]" + __main__.__file__[1:] + |
__main__.__file__[0] + "]" + __main__.__file__[1:] + |
||
"' | wc -l) > 1 ))") != 0</ |
"' | wc -l) > 1 ))") != 0</syntaxhighlight> |
||
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. |
||
Line 1,067: | Line 1,067: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(define *port* 12345) ; random large port number |
(define *port* 12345) ; random large port number |
||
Line 1,075: | Line 1,075: | ||
(printf "Working...\n") |
(printf "Working...\n") |
||
(sleep 10) |
(sleep 10) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,081: | Line 1,081: | ||
{{works with|rakudo|2018.03}} |
{{works with|rakudo|2018.03}} |
||
An old-school Unix solution, none the worse for the wear: |
An old-school Unix solution, none the worse for the wear: |
||
<lang |
<syntaxhighlight lang="raku" line>my $name = $*PROGRAM-NAME; |
||
my $pid = $*PID; |
my $pid = $*PID; |
||
Line 1,111: | Line 1,111: | ||
} |
} |
||
note "Got lock!"; |
note "Got lock!"; |
||
unlink $lockpid;</ |
unlink $lockpid;</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
{{works with|ARexx}} |
{{works with|ARexx}} |
||
Solutions using a temporary file as a semaphore aren't very clean; if the program ends abruptly, the file isn't cleaned up. In this solution, we will instead open an ARexx port of our own. Ports are automatically closed by the interpreter if the program is ABENDed. |
Solutions using a temporary file as a semaphore aren't very clean; if the program ends abruptly, the file isn't cleaned up. In this solution, we will instead open an ARexx port of our own. Ports are automatically closed by the interpreter if the program is ABENDed. |
||
< |
<syntaxhighlight lang="rexx">/* Simple ARexx program to open a port after checking if it's already open */ |
||
IF Show('PORTS','ROSETTA') THEN DO /* Port is already open; exit */ |
IF Show('PORTS','ROSETTA') THEN DO /* Port is already open; exit */ |
||
SAY 'This program may only be run in a single instance at a time.' |
SAY 'This program may only be run in a single instance at a time.' |
||
Line 1,133: | Line 1,133: | ||
END |
END |
||
EXIT 0</ |
EXIT 0</syntaxhighlight> |
||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
# Project : Determine if only one instance is running |
# Project : Determine if only one instance is running |
||
Line 1,159: | Line 1,159: | ||
end |
end |
||
return sum |
return sum |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 1,167: | Line 1,167: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Uses file locking on the program file |
Uses file locking on the program file |
||
< |
<syntaxhighlight lang="ruby">def main |
||
puts "first instance" |
puts "first instance" |
||
sleep 20 |
sleep 20 |
||
Line 1,181: | Line 1,181: | ||
end |
end |
||
__END__</ |
__END__</syntaxhighlight> |
||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |
||
< |
<syntaxhighlight lang="runbasic">if instr(shell$("tasklist"),"rbp.exe") <> 0 then print "Task is Running"</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Using TCP socket |
Using TCP socket |
||
< |
<syntaxhighlight lang="rust">use std::net::TcpListener; |
||
fn create_app_lock(port: u16) -> TcpListener { |
fn create_app_lock(port: u16) -> TcpListener { |
||
Line 1,211: | Line 1,211: | ||
// ... |
// ... |
||
remove_app_lock(lock_socket); |
remove_app_lock(lock_socket); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
===Java Interoperability=== |
===Java Interoperability=== |
||
{{Out}}Best seen running in your browser [https://scastie.scala-lang.org/ja0sMzt5SGKHSu3w8qnlQQ Scastie (remote JVM)]. |
{{Out}}Best seen running in your browser [https://scastie.scala-lang.org/ja0sMzt5SGKHSu3w8qnlQQ Scastie (remote JVM)]. |
||
< |
<syntaxhighlight lang="scala">import java.io.IOException |
||
import java.net.{InetAddress, ServerSocket} |
import java.net.{InetAddress, ServerSocket} |
||
Line 1,238: | Line 1,238: | ||
sys.exit(0) |
sys.exit(0) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby"># For this to work, you need to explicitly |
||
# store the returned fh inside a variable. |
# store the returned fh inside a variable. |
||
var fh = File(__FILE__).open_r |
var fh = File(__FILE__).open_r |
||
Line 1,252: | Line 1,252: | ||
say "Running..." |
say "Running..." |
||
Sys.sleep(20) |
Sys.sleep(20) |
||
say 'Done!'</ |
say 'Done!'</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
Uses NSDistributedNotificationCenter. Works with Swift 1.2. |
Uses NSDistributedNotificationCenter. Works with Swift 1.2. |
||
< |
<syntaxhighlight lang="swift">import Foundation |
||
let globalCenter = NSDistributedNotificationCenter.defaultCenter() |
let globalCenter = NSDistributedNotificationCenter.defaultCenter() |
||
Line 1,281: | Line 1,281: | ||
send() |
send() |
||
CFRunLoopRun()</ |
CFRunLoopRun()</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
{{works with|Tcl|8.6}} |
{{works with|Tcl|8.6}} |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6 |
||
try { |
try { |
||
# Pick a port number based on the name of the main script executing |
# Pick a port number based on the name of the main script executing |
||
Line 1,295: | Line 1,295: | ||
puts stderr "Application $::argv0 already running?" |
puts stderr "Application $::argv0 already running?" |
||
exit 1 |
exit 1 |
||
}</ |
}</syntaxhighlight> |
||
=={{header|TXR}}== |
=={{header|TXR}}== |
||
Line 1,301: | Line 1,301: | ||
==== Microsoft Windows ==== |
==== Microsoft Windows ==== |
||
< |
<syntaxhighlight lang="txrlisp">;;; Define some typedefs for clear correspondence with Win32 |
||
(typedef HANDLE cptr) |
(typedef HANDLE cptr) |
||
(typedef LPSECURITY_ATTRIBUTES cptr) |
(typedef LPSECURITY_ATTRIBUTES cptr) |
||
Line 1,325: | Line 1,325: | ||
) |
) |
||
(CloseHandle m)</ |
(CloseHandle m)</syntaxhighlight> |
||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
Line 1,331: | Line 1,331: | ||
{{works with|Bourne Shell}} |
{{works with|Bourne Shell}} |
||
{{works with|Bourne Again SHell}} |
{{works with|Bourne Again SHell}} |
||
<syntaxhighlight lang="sh"> |
|||
<lang sh> |
|||
# (c) Copyright 2005 Mark Hobley |
# (c) Copyright 2005 Mark Hobley |
||
# |
# |
||
Line 1,368: | Line 1,368: | ||
fi |
fi |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Visual Basic}}== |
=={{header|Visual Basic}}== |
||
Line 1,374: | Line 1,374: | ||
{{works with|Visual Basic|5}} |
{{works with|Visual Basic|5}} |
||
{{works with|Visual Basic|6}} |
{{works with|Visual Basic|6}} |
||
< |
<syntaxhighlight lang="vb">Dim onlyInstance as Boolean |
||
onlyInstance = not App.PrevInstance</ |
onlyInstance = not App.PrevInstance</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 1,383: | Line 1,383: | ||
Otherwise, the script completes normally and the special file is deleted just before it exits. |
Otherwise, the script completes normally and the special file is deleted just before it exits. |
||
< |
<syntaxhighlight lang="ecmascript">import "io" for File, FileFlags |
||
var specialFile = "wren-exclusive._sp" |
var specialFile = "wren-exclusive._sp" |
||
Line 1,409: | Line 1,409: | ||
System.print(sum) |
System.print(sum) |
||
File.delete(specialFile) // clean up</ |
File.delete(specialFile) // clean up</syntaxhighlight> |
||
{{out}} |
{{out}} |