FAQ
how to restrict the program run only one instance
what method can work on windows and Linux both system?

for example I have a program test.exe, I copy it to 2 dir
a/test.exe
b/test.exe
I want restrict the test.exe can only run one instance from each dir.

i tried open file use ModeExclusive,but it doesn't on windows.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Dave Cheney at Jan 22, 2014 at 4:29 am
    Listen on a port on localhost, this will block anybody else from binding to
    the same port until the first program exits.,

    On Wed, Jan 22, 2014 at 2:52 PM, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Shark Flh at Jan 22, 2014 at 5:10 am
    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe

    then a/test.exe and b/test.exe only one can run.
    I need both of it can run one instance.

    BTW, when program exit by accident , sometime the port will be locked, then
      it can't restart.

    On Wednesday, January 22, 2014 12:29:09 PM UTC+8, Dave Cheney wrote:

    Listen on a port on localhost, this will block anybody else from binding
    to the same port until the first program exits.,


    On Wed, Jan 22, 2014 at 2:52 PM, Shark Flh <flhs...@gmail.com<javascript:>
    wrote:
    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at Jan 22, 2014 at 5:21 am

    On Wed, Jan 22, 2014 at 4:10 PM, Shark Flh wrote:

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe

    then a/test.exe and b/test.exe only one can run.
    I need both of it can run one instance.

    BTW, when program exit by accident , sometime the port will be locked,
    then it can't restart.
    This is not true. When a program exits, any sockets owned by that process
    will be closed as well.

    On Wednesday, January 22, 2014 12:29:09 PM UTC+8, Dave Cheney wrote:

    Listen on a port on localhost, this will block anybody else from binding
    to the same port until the first program exits.,

    On Wed, Jan 22, 2014 at 2:52 PM, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.

    --
    You received this message because you are subscribed to the Google
    Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send
    an email to golang-nuts...@googlegroups.com.

    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • DV at Jan 22, 2014 at 4:33 am
    Not sure what the correct, cross-platform way to do this is, but at least
    on Windows, the recommended approach (and the one that has worked great for
    me) is to use the CreateSemaphore function. If the name you specify starts
    with "Global\", then the semaphore is unique for the entire system and a
    second attempt to open it will fail.

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682438(v=vs.85).aspx

    Getting this to work through cog shouldn't be too bad
    On Tuesday, January 21, 2014 8:52:34 PM UTC-7, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Shark Flh at Jan 22, 2014 at 5:13 am
    thanks, but I really need a cross-platform solution.
    On Wednesday, January 22, 2014 12:33:14 PM UTC+8, DV wrote:

    Not sure what the correct, cross-platform way to do this is, but at least
    on Windows, the recommended approach (and the one that has worked great for
    me) is to use the CreateSemaphore function. If the name you specify starts
    with "Global\", then the semaphore is unique for the entire system and a
    second attempt to open it will fail.


    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682438(v=vs.85).aspx

    Getting this to work through cog shouldn't be too bad
    On Tuesday, January 21, 2014 8:52:34 PM UTC-7, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Robert Johnstone at Jan 22, 2014 at 2:04 pm
    It may be easier to use the standard method on each platform, and then wrap
    that behaviour into a package. DV has gotten you halfway there. Now you
    just need a solution on linux... (depending on what platforms you are
    targeting).

    oneinstance_windows.go
    oneinstance_linux.go
    etc.


    On Wednesday, 22 January 2014 00:13:41 UTC-5, Shark Flh wrote:

    thanks, but I really need a cross-platform solution.
    On Wednesday, January 22, 2014 12:33:14 PM UTC+8, DV wrote:

    Not sure what the correct, cross-platform way to do this is, but at least
    on Windows, the recommended approach (and the one that has worked great for
    me) is to use the CreateSemaphore function. If the name you specify starts
    with "Global\", then the semaphore is unique for the entire system and a
    second attempt to open it will fail.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Hai Thanh Nguyen at Jan 22, 2014 at 8:39 am
    Just write something to a file somewhere. Everytime your program is run,
    check that file. You don't need any fancy functionalities to do this.
    On Wednesday, January 22, 2014 10:52:34 AM UTC+7, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Konstantin Khomoutov at Jan 22, 2014 at 10:15 am

    On Wed, 22 Jan 2014 00:39:08 -0800 (PST) Hai Thanh Nguyen wrote:

    Just write something to a file somewhere. Everytime your program is
    run, check that file. You don't need any fancy functionalities to do
    this.
    This fails if a program gets killed and has no chance to perform
    cleanup, so the file becomes stale. This moves us to the "PID file"
    concept famous in classic Unix daemons -- a new instance of the daemon
    is supposed to check if the PID file exists, and when it does whether
    the process with this PID file exists, and if it does whether its
    binary path name is that of the daemon. This is complicated and is
    inherently racey.

    So listening on a socket (not necessarily TCP -- Unix-domain socket
    would do as well; on Linux it's possible to create an UD-socket which
    does not physically exists on a file system) or connecting to d-bus and
    requesting a well-known name would do as well in a non-racey fashion.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Pollard Tom at Jan 23, 2014 at 6:16 am

    On Wednesday, January 22, 2014 5:15:04 AM UTC-5, Konstantin Khomoutov wrote:
    On Wed, 22 Jan 2014 00:39:08 -0800 (PST)
    Hai Thanh Nguyen <phai...@gmail.com <javascript:>> wrote:
    Just write something to a file somewhere. Everytime your program is
    run, check that file. You don't need any fancy functionalities to do
    this.
    [...] This moves us to the "PID file"
    concept famous in classic Unix daemons -- a new instance of the daemon
    is supposed to check if the PID file exists, and when it does whether
    the process with this PID file exists, and if it does whether its
    binary path name is that of the daemon. This is complicated and is
    inherently racey.
    PID files are not really that complicated. You can avoid race conditions
    by requiring any new process that wants to take over to acquire a lock
    while they're testing whether the process recorded in the lock file is
    still active or not; when they release the lock, they'll either have exited
    or overwritten the PID file with their own pid.

    So listening on a socket (not necessarily TCP -- Unix-domain socket
    would do as well; on Linux it's possible to create an UD-socket which
    does not physically exists on a file system) or connecting to d-bus and
    requesting a well-known name would do as well in a non-racey fashion.
    Listening on a socket is a good if you only want a single copy of the
    program running per machine, and you want it to be running all the time.
      (Otherwise, you would need to worry about losing your socket to some pther
    process.) If you wanted to have one copy of the process per user, or one
    per some other entity, then the PID file mechanism is a little more natural.

    Tom

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Andrew Walker at Sep 19, 2015 at 2:52 pm
    I took a stab at solving this for windows using the CreateSemaphore call,
    but have found it frustratingly elusive. From reading the documentation,
    creating a semaphore with the prefix "Global\", and then attempting to
    re-create it in another process will still return the handle,
    but GetLastError() should return ERROR_ALREADY_EXISTS. My code, however,
    always succeeds. GetLastError() always returns 0, and
    syscall.GetLastError() is always nil. Anyone see anything obvious that I'm
    missing?

    //oneinstance_windows.go
    package oneinstance

    import (
    "fmt"
    "syscall"
    "unsafe"
    )

    var (
    modkernel32 = syscall.NewLazyDLL("kernel32.dll")
    pCreateSemaphore = modkernel32.NewProc("CreateSemaphoreA")
    pGetLastError = modkernel32.NewProc("GetLastError")
    )

    func GetLastError() uint32 {
    ret, _, _ := pGetLastError.Call()
    return uint32(ret)
    }

    func GetInstance(ident string) error {
    semaphoreName := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`Global\`
    + ident)))
    //ret, _, _ := pCreateSemaphore.Call(
    pCreateSemaphore.Call(
    0,
    uintptr(1),
    uintptr(1),
    semaphoreName,
    )

    fmt.Println(GetLastError())
    fmt.Println(syscall.GetLastError())
    if GetLastError() != 0 {
    return syscall.GetLastError()
    }
    return nil
    }


    package main

    import (
    "fmt"
    "os"
    "time"

    "github.com/alaska/oneinstance"
    )

    func main() {
    err := oneinstance.GetInstance("foo")
    if err != nil {
    fmt.Println("Can't get semaphore:", err)
    os.Exit(1)
    }

    fmt.Println("Got semaphore")
    time.Sleep(10 * time.Second)
    }

    If I open two separate terminal windows and run the resultant exe, both of
    them will say "got semaphore" and pause.
    On Tuesday, January 21, 2014 at 10:52:34 PM UTC-5, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Andrew Walker at Sep 19, 2015 at 3:02 pm
    Incidentally, I get similar results when using CreateMutex

         pCreateMutex.Call(
             0,
             1,
             semaphoreName,
         )


    On Saturday, September 19, 2015 at 10:52:21 AM UTC-4, Andrew Walker wrote:

    I took a stab at solving this for windows using the CreateSemaphore call,
    but have found it frustratingly elusive. From reading the documentation,
    creating a semaphore with the prefix "Global\", and then attempting to
    re-create it in another process will still return the handle,
    but GetLastError() should return ERROR_ALREADY_EXISTS. My code, however,
    always succeeds. GetLastError() always returns 0, and
    syscall.GetLastError() is always nil. Anyone see anything obvious that I'm
    missing?

    //oneinstance_windows.go
    package oneinstance

    import (
    "fmt"
    "syscall"
    "unsafe"
    )

    var (
    modkernel32 = syscall.NewLazyDLL("kernel32.dll")
    pCreateSemaphore = modkernel32.NewProc("CreateSemaphoreA")
    pGetLastError = modkernel32.NewProc("GetLastError")
    )

    func GetLastError() uint32 {
    ret, _, _ := pGetLastError.Call()
    return uint32(ret)
    }

    func GetInstance(ident string) error {
    semaphoreName := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`Global\`
    + ident)))
    //ret, _, _ := pCreateSemaphore.Call(
    pCreateSemaphore.Call(
    0,
    uintptr(1),
    uintptr(1),
    semaphoreName,
    )

    fmt.Println(GetLastError())
    fmt.Println(syscall.GetLastError())
    if GetLastError() != 0 {
    return syscall.GetLastError()
    }
    return nil
    }


    package main

    import (
    "fmt"
    "os"
    "time"

    "github.com/alaska/oneinstance"
    )

    func main() {
    err := oneinstance.GetInstance("foo")
    if err != nil {
    fmt.Println("Can't get semaphore:", err)
    os.Exit(1)
    }

    fmt.Println("Got semaphore")
    time.Sleep(10 * time.Second)
    }

    If I open two separate terminal windows and run the resultant exe, both of
    them will say "got semaphore" and pause.
    On Tuesday, January 21, 2014 at 10:52:34 PM UTC-5, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Brainman at Sep 20, 2015 at 2:01 am

    On Sunday, 20 September 2015 00:52:21 UTC+10, Andrew Walker wrote:
    ... GetLastError() always returns 0,
    I am not surprised that GetLastError returns something inconsistent.
    GetLastError is returning error for the "last WinAPI call on current
    thread". How do you know Go runtime is not making WinAPI calls at random
    moments in your program? You should use pCreateSemaphore.Call return
    parameters instead. 3rd parameter will have GetLastError value in it at the
    time of CreateSemaphore call. You should, obviously, check CreateSemaphore
    return value (pCreateSemaphore.Call return value number 1) first, to decide
    if it succeeded or failed.

    Alex

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Andrew Walker at Sep 20, 2015 at 2:52 am
    Ugh, you're absolutely right. Error resolved. Package pending.
    On Saturday, September 19, 2015 at 10:01:02 PM UTC-4, brainman wrote:
    On Sunday, 20 September 2015 00:52:21 UTC+10, Andrew Walker wrote:
    ... GetLastError() always returns 0,
    I am not surprised that GetLastError returns something inconsistent.
    GetLastError is returning error for the "last WinAPI call on current
    thread". How do you know Go runtime is not making WinAPI calls at random
    moments in your program? You should use pCreateSemaphore.Call return
    parameters instead. 3rd parameter will have GetLastError value in it at the
    time of CreateSemaphore call. You should, obviously, check CreateSemaphore
    return value (pCreateSemaphore.Call return value number 1) first, to decide
    if it succeeded or failed.

    Alex
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ankurgupta1401 at Jun 4, 2016 at 2:30 pm
    The simplest solution would be to do it using MUTEX, here is how to do it
    <http://getgoingit.blogspot.in/2016/06/restrict-desktop-application-to-single.html> along
    with description.
    On Wednesday, 22 January 2014 09:22:34 UTC+5:30, Shark Flh wrote:

    how to restrict the program run only one instance
    what method can work on windows and Linux both system?

    for example I have a program test.exe, I copy it to 2 dir
    a/test.exe
    b/test.exe
    I want restrict the test.exe can only run one instance from each dir.

    i tried open file use ModeExclusive,but it doesn't on windows.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 22, '14 at 3:52a
activeJun 4, '16 at 2:30p
posts15
users10
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase