<p>First, Yes i know i have been flooding the Reddit, Sorry. There just aren't many places to find help for Go....</p>
<p>I am making a windows application, I want it to be so only one can be running at a time.</p>
<p>In Visual Basic .NET i would ether use the built in Single Instance or use Mutex by checking to see if a Mutex with the same keyword exists.</p>
<p>I read that some people use listening on a port to detect if another program is on the port, this will not work for me.</p>
<p>Is there some form of Mutex in Go? If so how?</p>
<hr/>**评论:**<br/><br/>antigiven: <pre><p>In Unix you'd store the PID of your process in a file in a known location. Then when your process starts, check that the file doesn't exist, or if it does exist check that the PID in the file isn't running anymore, and then overwrite the file with your new PID.</p>
<p>I don't know if that information is of any use to you in Windows.</p></pre>RedRossGeller: <pre><p>No, please don't do that. Listen on a domain socket instead e.g. <code>net.Listen("unix", "@/tmp/my-app")</code>.</p></pre>hahainternet: <pre><p>Please use <code>/run/</code> where possible</p></pre>singron: <pre><p>pid files are full of race conditions. You should just use flock, which is easier to use and actually works correctly. There are similar things in windows land I think.</p></pre>skroll: <pre><p>Generally you flock the pid file :)</p></pre>613style: <pre><p>Perhaps you can use <a href="https://github.com/golang/go/wiki/WindowsDLLs">this page</a> to call CreateMutex in kernel32.dll, and make a named mutex? Interestingly, even <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411(v=vs.85).aspx">Microsoft's documentation</a> recommends <a href="/u/antigiven">/u/antigiven</a> 's approach of using files:</p>
<blockquote>
<p>If you are using a named mutex to limit your application to a single instance, a malicious user can create this mutex before you do and prevent your application from starting. To prevent this situation, create a randomly named mutex and store the name so that it can only be obtained by an authorized user. Alternatively, you can use a file for this purpose. To limit your application to one instance per user, create a locked file in the user's profile directory.</p>
</blockquote>
<p>edit: To be honest, this is exactly the kind of problem you should just not care about. It will take up a ton of time, it will likely be frustrating at worst or uninteresting at best, and it's probably not a very important feature. Focus on the fun stuff when you can, then the important stuff, then this :)</p></pre>jerf: <pre><p>There are legitimate reasons to worry about this even beyond merely "not starting two instances accidentally"; if you're running a typical Windows program and you double-click on a type of file that program handles, in Windows you generally expect the already-open instance to open the file, not for a new instance to pop up.</p></pre>TheMerovius: <pre><blockquote>
<p>I read that some people use listening on a port to detect if another program is on the port, this will not work for me.</p>
</blockquote>
<p>Why not? That seems like an ingenious idea to me. Listen on some fixed port, whichever process listens has the lock.</p>
<p>So, by "this will not work for me", do you mean "I tried and it didn't work", or "I don't want to do that"? If the latter, why not?</p></pre>no1youknowz: <pre><p>If you need more places to ask questions. Try #go-nuts on freenode irc. Lots of helpful and knowledgable folks on there :)</p></pre>calebdoxsey: <pre><p>Here's one way to do it using a Mailslot:</p>
<pre><code>package main
import (
"fmt"
"log"
"os"
"syscall"
"unsafe"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procCreateMailslot = modkernel32.NewProc("CreateMailslotW")
)
func singleInstance(name string) error {
ret, _, _ := procCreateMailslot.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\\.\mailslot\`+name))),
0,
0,
0,
)
// If the function fails, the return value is INVALID_HANDLE_VALUE.
if int64(ret) == -1 {
return fmt.Errorf("instance already exists")
}
return nil
}
func main() {
log.SetFlags(0)
// pick a unique id here
err := singleInstance("ea49ee13-7118-4257-a3c2-0c22fc72310d")
if err != nil {
log.Fatalln(err)
return
}
log.Println("all good")
os.Stdin.Read([]byte{0})
}
</code></pre></pre>ecmdome: <pre><p>There is Mutex in Go but it's used to handle multi threaded requests... Not really sure if it would work in this situation.</p>
<p>Mutex is in the "sync" package </p></pre>antigiven: <pre><p>OP wants to prevent two processes from running at once. sync.Mutex only works within a single process.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传