Single Instance?

polaris · · 1589 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>First, Yes i know i have been flooding the Reddit, Sorry. There just aren&#39;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&#39;d store the PID of your process in a file in a known location. Then when your process starts, check that the file doesn&#39;t exist, or if it does exist check that the PID in the file isn&#39;t running anymore, and then overwrite the file with your new PID.</p> <p>I don&#39;t know if that information is of any use to you in Windows.</p></pre>RedRossGeller: <pre><p>No, please don&#39;t do that. Listen on a domain socket instead e.g. <code>net.Listen(&#34;unix&#34;, &#34;@/tmp/my-app&#34;)</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&#39;s documentation</a> recommends <a href="/u/antigiven">/u/antigiven</a> &#39;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&#39;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&#39;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 &#34;not starting two instances accidentally&#34;; if you&#39;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 &#34;this will not work for me&#34;, do you mean &#34;I tried and it didn&#39;t work&#34;, or &#34;I don&#39;t want to do that&#34;? 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&#39;s one way to do it using a Mailslot:</p> <pre><code>package main import ( &#34;fmt&#34; &#34;log&#34; &#34;os&#34; &#34;syscall&#34; &#34;unsafe&#34; ) var ( modkernel32 = syscall.NewLazyDLL(&#34;kernel32.dll&#34;) procCreateMailslot = modkernel32.NewProc(&#34;CreateMailslotW&#34;) ) 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(&#34;instance already exists&#34;) } return nil } func main() { log.SetFlags(0) // pick a unique id here err := singleInstance(&#34;ea49ee13-7118-4257-a3c2-0c22fc72310d&#34;) if err != nil { log.Fatalln(err) return } log.Println(&#34;all good&#34;) os.Stdin.Read([]byte{0}) } </code></pre></pre>ecmdome: <pre><p>There is Mutex in Go but it&#39;s used to handle multi threaded requests... Not really sure if it would work in this situation.</p> <p>Mutex is in the &#34;sync&#34; 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

1589 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传