Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk melaksanakan kunci fail dalam golang

Bagaimana untuk melaksanakan kunci fail dalam golang

青灯夜游
青灯夜游asal
2022-12-19 11:03:064914semak imbas

Dalam golang, anda boleh menggunakan api pakej penyegerakan untuk melaksanakan penguncian fail. Kunci fail (flock) adalah kunci nasihat untuk keseluruhan fail, iaitu, jika proses meletakkan kunci pada fail (inod), proses lain boleh mengetahuinya (kunci penasihat tidak memaksa proses untuk mematuhi panggilan itu); sintaks ialah "syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)".

Bagaimana untuk melaksanakan kunci fail dalam golang

Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.

Apabila kami menggunakan bahasa Go untuk membangunkan beberapa program, berbilang proses selalunya beroperasi pada fail yang sama pada masa yang sama, yang boleh menyebabkan kekeliruan data dalam fail dengan mudah. Pada masa ini, kita perlu menggunakan beberapa cara untuk mengimbangi konflik ini, dan kunci fail (kawanan) wujud. Mari kita perkenalkan di bawah.

Untuk flock, contoh yang paling biasa ialah Nginx Selepas proses berjalan, PID semasa akan ditulis ke dalam fail ini, jika fail ini sudah wujud, iaitu proses sebelumnya belum keluar. maka Nginx Ia tidak akan dimulakan semula, jadi kumpulan juga boleh digunakan untuk mengesan sama ada proses itu wujud.

kawanan ialah kunci nasihat untuk keseluruhan fail. Dalam erti kata lain, jika proses meletakkan kunci pada fail (inod), proses lain boleh mengetahuinya (kunci nasihat tidak memaksa proses untuk mematuhi). Bahagian yang terbaik ialah parameter pertamanya ialah deskriptor fail, dan apabila deskriptor fail ditutup, kunci dilepaskan secara automatik. Apabila proses ditamatkan, semua deskriptor fail akan ditutup. Selalunya tidak perlu mempertimbangkan perkara seperti membuka kunci atom.

Sebelum memperkenalkannya secara terperinci, mari kita perkenalkan kod dahulu

package main
import (
    "fmt"
    "os"
    "sync"
    "syscall"
    "time"
)
//文件锁
type FileLock struct {
    dir string
    f   *os.File
}
func New(dir string) *FileLock {
    return &FileLock{
        dir: dir,
    }
}
//加锁
func (l *FileLock) Lock() error {
    f, err := os.Open(l.dir)
    if err != nil {
        return err
    }
    l.f = f
    err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
    if err != nil {
        return fmt.Errorf("cannot flock directory %s - %s", l.dir, err)
    }
    return nil
}
//释放锁
func (l *FileLock) Unlock() error {
    defer l.f.Close()
    return syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)
}
func main() {
    test_file_path, _ := os.Getwd()
    locked_file := test_file_path
    wg := sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(num int) {
            flock := New(locked_file)
            err := flock.Lock()
            if err != nil {
                wg.Done()
                fmt.Println(err.Error())
                return
            }
            fmt.Printf("output : %d\n", num)
            wg.Done()
        }(i)
    }
    wg.Wait()
    time.Sleep(2 * time.Second)
}

Apabila menjalankan kod di atas di bawah sistem Windows, ralat berikut akan muncul:

Bagaimana untuk melaksanakan kunci fail dalam golang

Ini kerana sistem Windows tidak menyokong kunci pid, jadi kita perlu menjalankan program di atas secara normal di bawah sistem Linux atau Mac.

Kod di atas menunjukkan permulaan 10 goroutine pada masa yang sama, tetapi semasa menjalankan program, hanya satu goroutine boleh mendapatkan kunci fail (kawanan). Goroutinue lain akan membuang maklumat pengecualian selepas gagal mendapatkan kumpulan. Ini boleh mencapai kesan bahawa hanya satu proses dibenarkan untuk mengakses fail yang sama dalam tempoh tertentu.

Panggilan kunci fail khusus dalam kod:

syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)

Kami menggunakan syscall.LOCK_EX, syscall.LOCK_NB Apakah maksudnya?

kawanan ialah kunci nasihat dan tidak wajib. Satu proses menggunakan flock untuk mengunci fail, dan satu lagi proses boleh mengendalikan fail yang sedang dikunci dan mengubah suai data dalam fail Sebabnya ialah flock hanya digunakan untuk mengesan sama ada fail tersebut telah dikunci , satu lagi proses Dalam kes menulis data, kernel tidak akan menyekat operasi tulis proses ini, yang merupakan strategi pemprosesan kernel bagi kunci nasihat.

kawanan mempunyai tiga jenis operasi utama:

  • LOCK_SH: Kunci kongsi, berbilang proses boleh menggunakan kunci yang sama, selalunya digunakan sebagai kunci kongsi baca

  • LOCK_EX: Kunci eksklusif, hanya dibenarkan digunakan oleh satu proses pada masa yang sama, selalunya digunakan sebagai kunci tulis; .

  • Apabila proses menggunakan flock untuk cuba mengunci fail, jika fail sudah dikunci oleh proses lain, proses itu akan disekat sehingga kunci dilepaskan atau parameter LOCK_NB adalah digunakan apabila memanggil kawan. Apabila cuba mengunci fail, didapati ia telah dikunci oleh perkhidmatan lain, dan ralat akan dikembalikan dengan kod ralat EWOULDBLOCK.

  • Pelepasan kunci kawanan adalah sangat unik Anda boleh memanggil parameter LOCK_UN untuk melepaskan kunci fail, atau anda boleh melepaskan kunci fail dengan menutup fd (parameter pertama bagi kawanan ialah fd), yang bermaksud kawanan. akan Ia dikeluarkan secara automatik apabila proses ditutup.

Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati:

Video Pengaturcaraan

! !

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan kunci fail dalam golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn