Как создать файл .lock в golang и удалить его перед выходом? - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь запретить программе открывать другой экземпляр, если он уже открыт, для этого я создаю файл с расширением .lock и удаляю его при выходе из программы. Однако все, кроме удаления, работает.

package main

import (
    "os"
    "os/signal"
    "fmt"
)

func main() {
    var test string
    exitsig := make(chan os.Signal, 1)
    signal.Notify(exitsig, os.Interrupt)
    var (
        lockstate bool = false
    )

    if _, err := os.Stat("ms.lock"); err == nil {
      return

    } else if os.IsNotExist(err) {
      var file, err = os.Create("ms.lock")
        if err != nil {
            return
        }
        file.Close()
        lockstate = true
    }

    go func() {
      <- exitsig
        fmt.Println("Error removing file")
        fmt.Scanf("%s", &test)
        if lockstate {
            var err = os.Remove("ms.lock")
            if err != nil {
                fmt.Println("Error removing file")
                fmt.Scanf("%s", &test)
            }
        }
      os.Exit(0)
    }()

}

Я пытался выйти по ctrl+c, выходя нажатием кнопки закрытия в правом верхнем углу окна, но он никогда не посылает сигнал, os.Interrupt сигнал никогда не ловится. В чем причина этого?

Кроме того, мне нужен сигнал, не зависящий от платформы, поэтому он должен работать как на Windows, так и на Unix-системах.

1 Ответ

1 голос
/ 07 октября 2019

Я думаю, это потому, что ваша основная функция существует вскоре после запуска программы. Если основная функция завершится, все запущенные программы тоже умрут.

Вот код, который мне подходит:

package main

import (
    "fmt"
    "os"
    "os/signal"
    "sync"
)

func main() {

    exitsig := make(chan os.Signal, 1)
    signal.Notify(exitsig, os.Interrupt)
    var (
        lockstate bool = false
    )

    if _, err := os.Stat("ms.lock"); err == nil {
        return

    } else if os.IsNotExist(err) {
        var file, err = os.Create("ms.lock")
        if err != nil {
            return
        }
        file.Close()
        lockstate = true
    }

    go func() {
        <-exitsig
        if lockstate {
            var err = os.Remove("ms.lock")
            if err != nil {
                fmt.Println("Error removing file: ", err)
            }
        }
        os.Exit(0)
    }()

    wg := &sync.WaitGroup{}
    wg.Add(1)
    wg.Wait()

}

Я добавил группу ожидания для ожидания в главном потоке. Отлично работает на MacOS - создает файл ms.lock и ждет. Убив его с помощью Cmd + C, вы удалите файл.

Должен работать в любом месте, пока сигнал срабатывает.

...