Boring look at the project compile script runtime throws the process already exists is how to implement

First edition:

We use the presence or absence of a file to indicate whether a process is executing (obviously a file-pid file for each process).

Package main import (" FMT "" OS" "time") func main() {// 1 Define the current PID file sigFILE := "./cli_syncStaffs. PID "_, Err := os.stat (sigfile) if err == nil {// The pid file exists - the process already exists fmt.Println(" pid file exist. Running... ) OS. Exit (0)} / / 2 to create the current process of pid file pidFileHandle, err: = OS. OpenFile (sigfile, OS O_RDONLY | OS. O_CREATE, os.ModePerm) if err ! Println(time.now ().format ("2006-01-02 15:04:05")) time.sleep (25* time.second) Format("2006-01-02 15:04:05")) // Err = pidFilehandle.close () if err! =nil {fmt.println (err)} // Delete the file err = os.remove (sigfile) if err! =nil { fmt.Println(err) } }Copy the code

Thus, if one process is executing while another process is executing, it will throw:

However, when the number of concurrent requests is large (let’s simulate 10 concurrent requests below)

package main import ( "fmt" "os" "sync" "time" ) var wg sync.WaitGroup func main() { for i :=0 ; i<10 ; I ++{fmt.println ("start ", I) wg.add (1) go test() // start 10 goroutines to calculate} // block - ensure that the subcoroutine runs out wg.wait ()} func test(){defer Wg.done () // 1 Define the current process PID file sigfile := "./cli_syncStaffs. PID "_, Err := os.stat (sigfile) if err == nil {// The pid file exists - the process already exists fmt.Println(" pid file exist. Running... Return} / / 2 to create the current process of pid file pidFileHandle, err: = OS. The OpenFile (sigfile, OS O_RDONLY | OS. O_CREATE, OS. ModePerm) if err! Println(time.now ().format ("2006-01-02 15:04:05")) = nil {fmt.println (err) return} Time.sleep (5* time.second) fmt.println (time.now ().format ("2006-01-02 15:04:05"))) // Err = pidFilehandle.close () if err! =nil {fmt.Println(err) return} // Delete the file err = os.Remove(sigfile) if err! =nil { fmt.Println(err) return } }Copy the code

Obviously, no matter how fast the coroutine is, it is ordered, that is, only one of the 10 coroutines will output the timestamp (all the others will tell the PID file exists, running…).

But the output looks like this

As you can see, simply relying on the existence of a file does not guarantee that other processes will not be able to execute when a process executes

We should lock the file (concurrency security),

When a file cannot be locked, a process is running

So change the program:

package main import ( "fmt" "os" "sync" "syscall" "time" ) var wg sync.WaitGroup func main() { for i :=0 ; i<10 ; I ++{fmt.println ("start ", I) wg.add (1) go test() // start 10 goroutines to calculate} // block - ensure that the subcoroutine runs out wg.wait ()} func test(){defer Wg.done () // 1 Set PID file sigfile := "./cli_syncStaffs. PID" err := os.OpenFile(sigfile, os.O_RDONLY|os.O_CREATE, os.ModePerm) if err ! = nil {fmt.println ("open fail.") fmt.println (err) return} defer pidFilehandle.close () // 2 File lock err = syscall.Flock(int(pidFileHandle.Fd()), syscall.LOCK_EX|syscall.LOCK_NB) if err ! = nil { fmt.Println(err) fmt.Println("running..." ) return } defer syscall.Flock(int(pidFileHandle.Fd()), Println(time.now ().format ("2006-01-02 15:04:05")) time.sleep (5* time.second) fmt.Println(time.Now().Format("2006-01-02 15:04:05")) return }Copy the code

Note: File locking is not supported on Windows

Correct output above:

start 0 start 1 start 2 start 3 start 4 start 5 start 6 start 7 start 8 start 9 resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... resource temporarily unavailable running... The 2020-11-20 01:42:05 2020-11-20 01:42:10Copy the code

Reference blog:

https://www.cnblogs.com/pingyeaa/p/11418527.html
Copy the code