It is necessary to do that if the program is already running, so that the duplicate copy does not start.
How to do this on golang?
- In Windows, who develops window programs on pure WinAPI, if I'm not mistaken, they usually check the registration of the class of their window. If there is, then one copy of the program is already running. In common frameworks, this is already a built-in function. If there is no such player in the goal, then you need to go deeper into WINAPI or think up your own way to inherit your program so that it can be seen that it works. In linux, for example, pid-files are left in the designated place. And then they are checked and whether the process whose id is recorded is alive. In extreme cases, you can do the same in Windows. - Sergey
3 answers
Save in the working directory of the program at startup the file with PID. But before this, check that there is no process in the system with this PID, if there is - you say that the copy is running.
Getpid is the current PID of the process.
FindProcess - search for a process by PID, though under UNIX, os.Process always returns, regardless of whether it exists or not, and it will be necessary to check if this process really exists (ask the current PID?).
- How to atomize reading and writing a file? - vp_arth
- Only detours. For example, create another file using // BEGIN critical section lock_file, err: = os.OpenFile ("/ tmp / mylock.lock", flag int, os.O_CREATE | os. O_EXCL) if err! = Nil {// we are not alone //} // create a PID file err: = os.Remove ("/ tmp / mylock.lock") // END critical section The key point here is "os.O_CREATE | os. O_EXCL" - Darigaaz
- Or use something ready- made like godoc.org/github.com/nightlyone/lockfile#example-Lockfile - Darigaaz
You can open the file in exclusive mode. If opened - well and you work. No - it means the program is already running.
An example for windows can be found here: https://github.com/rekby/lockrun/blob/master/lockrun_windows.go
for linux, you can see http://www.unixwiz.net/tools/lockrun.c - C code, but simple.
Depending on the OS, you need to use different commands to get a list of processes, but the essence is about the same:
func isProcRunning(names ...string) (bool, string, error) { if len(names) == 0 { return false, "", nil } cmd := exec.Command("tasklist.exe", "/fo", "csv", "/nh") cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: false} out, err := cmd.Output() if err != nil { return false, "", err } for _, name := range names { if bytes.Contains(out, []byte(name)) { return true, name, nil } } return false, "", nil } - You transfer the name / names to the function (you can use the PID, whichever is more convenient) of the process
- you run a utility that opens a list of all processes (with the necessary flags)
- Are you looking for the necessary names or Id in the utility output?
Example of use:
func main() { isRunning, name, _ := isProcRunning("excel.exe") fmt.Println("Is excel.exe running: ", isRunning) isRunning, name, _ = isProcRunning("iexplore.exe", "firefox.exe", "chrome.exe") flag := false switch name { case "iexplore.exe": fmt.Println("Is iexplore.exe running: ", isRunning) fmt.Println("Is firefox.exe running: ", flag) fmt.Println("Is chrome.exe running: ", flag) break case "firefox.exe": fmt.Println("Is iexplore.exe running: ", flag) fmt.Println("Is firefox.exe running: ", isRunning) fmt.Println("Is chrome.exe running: ", flag) break case "chrome.exe": fmt.Println("Is iexplore.exe running: ", flag) fmt.Println("Is firefox.exe running: ", flag) fmt.Println("Is chrome.exe running: ", isRunning) break default: fmt.Println("Is iexplore.exe running: ", flag) fmt.Println("Is firefox.exe running: ", flag) fmt.Println("Is chrome.exe running: ", flag) } }