似乎没有跨平台解决方案(除了编写文件,并在开始时查找该文件).
在Windows上,此线程报告
推荐的方法(以及对我有用的
CreateSemaphore方法)是使用该功能.
如果您指定的名称以"Global\" 开头,则信号量对于整个系统是唯一的,第二次尝试打开它将失败.
kostix在评论中添加:
查看围绕pkg\syscall层次结构的Go源代码 - 它包含大量关于如何使用系统调用来调用Windows上的DLL的示例(这就是您在Windows API中访问任何内容的方式).
那就是syscall/dll_windows.go.(这是一个要点)
我知道这个话题有点旧,但我最近在 Windows 上需要它,我会在这里发布我是如何做到的,以防其他人需要。
感谢@VonC 为我指明了正确的方向。
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procCreateMutex = kernel32.NewProc("CreateMutexW")
)
func CreateMutex(name string) (uintptr, error) {
ret, _, err := procCreateMutex.Call(
0,
0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(name))),
)
switch int(err.(syscall.Errno)) {
case 0:
return ret, nil
default:
return ret, err
}
}
// mutexName starting with "Global\" will work across all user sessions
_, err := CreateMutex("SomeMutexName")
Run Code Online (Sandbox Code Playgroud)
我用一个更完整的例子创建了一个库:https : //github.com/rodolfoag/gow32
谢谢!
您可以使用套接字,简单易用并且可以真正处理所有事情。
package main
import (
"fmt"
"net"
"os"
"strings"
)
const (
INSTANCE_PORT = 9292
)
func main() {
listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", INSTANCE_PORT))
if err != nil {
if strings.Index(err.Error(), "in use") != -1 {
//optionally send command line arguments to the other instance
fmt.Fprintln(os.Stderr, "Already running.")
return
} else {
panic(err)
}
}
for {
conn, err := listener.Accept()
if err != nil {
println("Error accept:", err.Error())
return
}
go do_something_with(conn)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2689 次 |
| 最近记录: |