golang では、同期パッケージの API を使用してファイル ロックを実装できます。ファイル ロック (flock) は、ファイル全体に対する勧告的ロックです。つまり、プロセスがファイル (inode) にロックを設定すると、他のプロセスはそれを知ることができます (勧告的ロックは、プロセスの準拠を強制しません)、ファイル ロックの呼び出し構文は「syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)」です。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
Go 言語を使用してプログラムを開発する場合、複数のプロセスが同じファイルに対して同時に動作することがよくあり、ファイル内のデータが混乱しやすくなります。このとき、これらの矛盾を何らかの手段でバランスさせる必要があり、ファイルロック(flock)が登場しましたので、以下に紹介しましょう。
flock の場合、最も一般的な例は Nginx です。プロセスの実行後、現在の PID がこのファイルに書き込まれます。もちろん、このファイルがすでに存在する場合、つまり前のプロセスが終了していない場合は、 Nginx は再起動しないので、flock を使用してプロセスが存在するかどうかを検出することもできます。
flock は、ファイル全体に対する勧告的なロックです。言い換えれば、プロセスがファイル (inode) にロックを設定すると、他のプロセスはそれを知ることができます (勧告ロックはプロセスの遵守を強制しません)。最も優れた点は、最初のパラメータがファイル記述子であり、このファイル記述子が閉じられるとロックが自動的に解放されることです。プロセスが終了すると、すべてのファイル記述子が閉じられます。多くの場合、アトミック ロックの解除などを考慮する必要はありません。
詳しく紹介する前に、まずコードを紹介しましょう
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) }
Windows システムで上記のコードを実行すると、次のエラーが表示されます:
## これは、Windows システムが pid ロックをサポートしていないためで、上記のプログラムを Linux または Mac システムで通常どおり実行する必要があります。 上記のコードは 10 個の goroutine を同時に開始することを示していますが、プログラムの実行中にファイル ロック (flock) を取得できるのは 1 つの goroutine だけです。他のゴルーチンは、flock の取得に失敗した後に例外情報をスローします。これにより、指定された期間内に 1 つのプロセスのみが同じファイルにアクセスできるようにする効果が得られます。 コード内のファイル ロックの具体的な呼び出し:syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)syscall.LOCK_EX、syscall.LOCK_NB を使用しますが、これは何を意味しますか? flock は勧告的なロックであり、必須ではありません。 1 つのプロセスは flock を使用してファイルをロックし、もう 1 つのプロセスはロックされているファイルを直接操作してファイル内のデータを変更できます。その理由は、flock はファイルがロックされているかどうかを検出するためにのみ使用されるためです。 、別のプロセス データを書き込む場合、カーネルはこのプロセスの書き込み操作をブロックしません。これは、勧告ロックのカーネル処理戦略です。 flock には 3 つの主要な操作タイプがあります:
プログラミング ビデオをご覧ください。 !
以上がgolangでファイルロックを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。