mysql 原子鎖 Go語言檔案鎖操作

2021-10-17 17:04:47 字數 1726 閱讀 5595

我們使用go語言開發一些程式的時候,往往出現多個程序同時操作同一份檔案的情況,這很容易導致檔案中的資料混亂。這時我們就需要採用一些手段來平衡這些衝突,檔案鎖(flock)應運而生,下面我們就來介紹一下。

對於 flock,最常見的例子就是 nginx,程序執行起來後就會把當前的 pid 寫入這個檔案,當然如果這個檔案已經存在了,也就是前乙個程序還沒有退出,那麼 nginx 就不會重新啟動,所以 flock 還可以用來檢測程序是否存在。

flock 是對於整個檔案的建議性鎖。也就是說,如果乙個程序在乙個檔案(inode)上放了鎖,其它程序是可以知道的(建議性鎖不強求程序遵守)。最棒的一點是,它的第乙個引數是檔案描述符,在此檔案描述符關閉時,鎖會自動釋放。而當程序終止時,所有的檔案描述符均會被關閉。所以很多時候就不用考慮類似原子鎖解鎖的事情。

在具體介紹前,先上**

package main

import (

"fmt"

"os"

"sync"

"syscall"

"time"

//檔案鎖

type filelock struct

for i := 0; i < 10; i++ (i)

wg.wait()

time.sleep(2 * time.second)

在 windows 系統下執行上面的**會出現下面的錯誤:

undefined: syscall.flock

undefined: syscall.lock_ex

undefined: syscall.lock_nb

undefined: syscall.flock

undefined: syscall.lock_un

這是因為 windows 系統不支援 pid 鎖,所以我們需要在 linux 或 mac 系統下才能正常執行上面的程式。

上面**中演示了同時啟動 10 個 goroutinue,但在程式執行過程中,只有乙個 goroutine 能獲得檔案鎖(flock)。其它的 goroutinue 在獲取不到 flock 後,會丟擲異常的資訊。這樣即可達到同一檔案在指定的週期內只允許乙個程序訪問的效果。

**中檔案鎖的具體呼叫:

syscall.flock(int(f.fd()), syscall.lock_ex|syscall.lock_nb)

我們採用了 syscall.lock_ex、syscall.lock_nb,這是什麼意思呢?

flock 屬於建議性鎖,不具備強制性。乙個程序使用 flock 將檔案鎖住,另乙個程序可以直接操作正在被鎖的檔案,修改檔案中的資料,原因在於 flock 只是用於檢測檔案是否被加鎖,針對檔案已經被加鎖,另乙個程序寫入資料的情況,核心不會阻止這個程序的寫入操作,也就是建議性鎖的核心處理策略。

flock 主要三種操作型別:

lock_sh:共享鎖,多個程序可以使用同一把鎖,常被用作讀共享鎖;

lock_ex:排他鎖,同時只允許乙個程序使用,常被用作寫鎖;

lock_un:釋放鎖。

程序使用 flock 嘗試鎖檔案時,如果檔案已經被其他程序鎖住,程序會被阻塞直到鎖被釋放掉,或者在呼叫 flock 的時候,採用 lock_nb 引數。在嘗試鎖住該檔案的時候,發現已經被其他服務鎖住,會返回錯誤,錯誤碼為 ewouldblock。

flock 鎖的釋放非常具有特色,即可呼叫 lock_un 引數來釋放檔案鎖,也可以通過關閉 fd 的方式來釋放檔案鎖(flock 的第乙個引數是 fd),意味著 flock 會隨著程序的關閉而被自動釋放掉。

原子操作 普通鎖 讀寫鎖

一 原子操作cas compare and swap 原子操作分三步 讀取addr的值,和old進行比較,如果相等,則將new賦值給 addr,他能保證這三步一起執行完成,叫原子操作也就是說它不能再分了,當有乙個cpu在訪問這塊內容addr時,其他cpu就不能訪問 text compareandsw...

mySQL無鎖佇列 go 無鎖佇列

無鎖佇列適用場景 兩個執行緒之間的互動資料,乙個執行緒生產資料,另外乙個執行緒消費資料,效率高 缺點 需要使用固定分配的空間,不能動態增加 減少長度,存在空間浪費和無法擴充套件空間問題 package main import fmt reflect strings time type loopque...

go語言中的鎖

雖然提供了channel來保證協程中的通訊,在某些情況下,還是更適合使用鎖來保證執行緒的安全.go語言中的鎖分兩種 互斥鎖mutex和讀寫鎖rwmutex 1.互斥鎖 mutex 互斥鎖是執行緒安全中最常用的鎖,基本原理就是對某個操作進行加鎖,無論讀寫同一時間內只有乙個協程可以對當前資料進行操作,只...