被遺忘的桃源——flock 檔案鎖
緣起
在後臺開發中,隨著多執行緒應用日益增多,人們對多程序的關注也在逐漸減弱。但是在實際應用中,多程序之間的通訊及資源共享,還是會不時的遇到,如果不認真處理,就會出現資料異常,甚至導致系統資源耗盡的情形。今天,我在這裡為大家介紹一下 flock 檔案鎖——一個處理多個程序間檔案共享衝突、解決crontab 中單任務多例項問題的利器。
在開發過程中,經常會出現這樣一種情況:服務依賴的資料變動不是特別頻繁,例如天或周級別的更新。這類資料通常是格式化後儲存在資料檔案中,即以資料檔案的形式進行資料更新。
檔案的更新的基本流程如下:
可以看出,對同一個檔案,有兩個不同的程序在分別進行寫和讀,這就出現了多程序下對檔案的讀寫衝突問題。在這種場景下的多程序讀寫檔案衝突,與常規的多程序讀寫衝突是有區別的。主要區別的點在於,常規的多程序是同一服務中通過 fork 派生出來的多程序,讀寫衝突通常是對記憶體中的資料結構進行讀寫時發生的。而資料檔案更新場景下的多程序,產生衝突的操作物件是檔案,而且這裡的程序可能是兩個獨立的、無任何關係的程序,例如寫程序是python 指令碼,而讀程序是一個 C++ 服務。由於檔案讀寫程序的獨立性,對這種讀寫衝突的處理需要作業系統層面的支援。
檔案鎖 flock
為解決多程序對同一檔案的讀寫衝突,在linux 系統中,提供了 flock 這一系統呼叫,用來實現對檔案的讀防寫,即檔案鎖的功能。檔案鎖保護檔案的功能,與 fork 多程序及 pthread 庫中多執行緒使用讀寫鎖來保護記憶體資源的方式是類似的。 flock 的 man page 中有如下介紹:
flock - apply or remove an advisory lock on an open file
從中可以解讀出兩點內容:
- flock 提供的檔案鎖是建議性質的。所謂 “建議性鎖”,通常也叫作非強制性鎖,即一個程序可以忽略其他程序加的鎖,直接對目標檔案進行讀寫操作。因而,只有當前程序主動呼叫 flock去檢測是否已有其他程序對目標檔案加了鎖,檔案鎖才會在多程序的同步中起到作用。表述的更明確一點,就是如果其他程序已經用 flock 對某個檔案加了鎖,當前程序在讀寫這一檔案時,未使用 flock 加鎖(即未檢測是否已有其他程序鎖定檔案),那麼當前程序可以直接操作這一檔案,其他程序加的檔案鎖對當前程序的操作不會有任何影響。這就種可以被忽略、需要雙方互相檢測確認的加鎖機制,就被稱為 ”建議性“ 鎖。
- 從man page 的描述中還可以看到,檔案鎖必須作用在一個開啟的檔案上,即從應用的角度看,檔案鎖應當作用於一個開啟的檔案控制代碼上。知所以需要對開啟的檔案加鎖,是和 linux 檔案系統的實現方式、及多程序下鎖定檔案的需求共同決定的,在下文對其原理有詳細介紹。
共享鎖與排他鎖
linux 中 flock 系統呼叫的原型如下:
#include <sys/file.h>
int flock(int fd, int operation);
當 flock 執行成功時,會返回0;當出現錯誤時,會返回 -1,並設定相應的 errno 值。
在flock 原型中,引數 operation 可以使用 LOCK_SH 或 LOCK_EX 常量,分別對應共享鎖和排他鎖。這兩個常量的定義在 file.h 中。與 flock 相關的常量定義如下:
/* Operations for the `flock' call. */
#define LOCK_SH 1 /* Shared lock. */
#define LOCK_EX 2 /* Exclusive lock. */
#define LOCK_UN 8 /* Unlock. */
/* Can be OR'd in to one of the above. */
#define LOCK_NB 4 /* Don't block when locking. */
當使用 LOCK_SH 共享鎖時,多個程序可以都使用共享鎖鎖定同一個檔案,從而實現多個程序對檔案的並行讀取。由此可見,LOCK_SH 共享鎖類似於多執行緒讀寫鎖 pthread_rwlock_t 型別中的讀鎖。當使用LOCK_EX 排他鎖時,同一時刻只能有一個程序鎖定成功,其餘進行只能阻塞(阻塞與非阻塞在下文介紹),這種行為與多執行緒讀寫鎖中的寫鎖類似。
以兩個程序為例,假設程序1先對檔案加了鎖,而後程序2又嘗試對同一檔案加鎖,這時程序2的行為如下表所示:
程序1 (先加鎖) | 程序2(後加鎖) | 程序2表現 |
---|---|---|
LOCK_SH | LOCK_SH | 不阻塞 |
LOCK_SH | LOCK_EX | 阻塞 |
LOCK_EX | LOCK_SH | 阻塞 |
LOCK_EX | LOCK_EX | 阻塞 |
可見,只有兩個程序都對檔案加的都是共享鎖時,程序可以正常執行,不會阻塞,其他情形下,後加鎖的程序都會被阻塞。
在 flock 的man page 中,關於檔案鎖的互斥有如下描述:
A call to flock() may block if an incompatible lock is held by another process.
這裡所說的不相容的鎖就是指會導致阻塞的兩個鎖,上面表格中後三行中的鎖,都是兩兩不相容的,只有第一行的兩個共享鎖是相容的。
阻塞與非阻塞
flock 檔案鎖提供了阻塞和非阻塞兩種使用方式。當處於阻塞模式時,如果當前程序無法成功獲取到檔案鎖,那麼程序就會一直阻塞等待,直到其他程序在對應檔案上釋放了鎖,本程序能成功持有鎖為止。在預設情況下,flock 提供是阻塞模式的檔案鎖。
在日常使用中,檔案鎖還會使用在另外一種場景下,即程序首先嚐試對檔案加鎖,當加鎖失敗時,不希望程序阻塞,而是希望 flock 返回錯誤資訊,程序進行錯誤處理後,繼續進行下面的處理。在這種情形下就需要使用 flock 的非阻塞模式。把flock 的工作模式設定為非阻塞模式非常簡單,只要將原有的 operation 引數改為鎖的型別與 LOCK_NB 常量進行按位或操作即可,例如:
int ret = flock(open_fd, LOCK_SH | LOCK_NB);
int ret = flock(open_fd, LOCK_EX | LOCK_NB);
在非阻塞模式下,加檔案鎖失敗並不影響程序流程的執行,但要注意加入錯誤處理邏輯,在加鎖失敗時,不能對目標檔案進行操作。
flock 實現細節
在flock 的 man page 中有關於 flock 細節的一些描述。其中說明了flock 是與開啟檔案的檔案表項相關聯的。根據《Unix 環境高階程式設計》對開啟檔案的介紹,開啟的檔案在程序表和作業系統中的對應的結構如下圖所示:
每個程序在程序表中都一個對應的專案,叫做程序表項,上圖是最左邊展示了程序表中兩程序表項,分別對應兩個獨立的程序。在程序表項中,有一個檔案描述符表,其中儲存了所有本程序開啟的檔案描述符資訊及指向對應檔案表項的指標。而作業系統中,還另外有一張表,叫做檔案表,其中儲存的是系統中所有程序開啟的檔案的相關資訊,其中的專案叫做檔案表項(上圖中間藍色部分)。
在程序表項的檔案描述符表中每個描述符都對應一個檔案表項指標,指向檔案表中的一項。v 節點表中的專案稱為 v 節點表項,可以認為其中儲存了真正的檔案內容。
從圖中可以看出,程序1對同一個檔案打開了兩次,分別對應本程序中的檔案描述符 fd0 和 fd2。而下面的程序對這個檔案又打開了一次,對應此程序中的 fd1描述符。要注意的是,不論是同一程序還是不同的程序,對同一檔案開啟時,都建立了與各fd 對應的獨立的檔案表項。
在flock 的man page 中關於檔案表項有如下描述:
Locks created by flock() are associated with an open file table entry.
這說明程序使用 flock 對已開啟檔案加檔案鎖時,是加在了上圖中間藍色部分的檔案表項上。假如圖中位於下方的程序對fd1 加上了排他鎖,實際就是加在了fd1 指向的檔案表項上,這時上方的程序對 fd0 或 fd2 再加任何型別的檔案鎖都會失敗。這是因為作業系統會檢測到上方的兩個檔案表項和下方的檔案表項都指向了相同的 v 節點,並且下方的檔案表項已經加了排他鎖,這時如果其他指向相同v 節點的檔案表項再想嘗試加上與原有鎖型別不相容的檔案鎖時,作業系統會將此檔案表項對應的程序阻塞。
呼叫dup 、 fork、execve 時的檔案鎖
如果要了解用 dup 複製檔案描述符時和使用 fork 產生子程序時的檔案鎖表現,就要了解在呼叫這兩個函式時,描述符對應的資料結構發生了哪些變化。
使用 dup 複製檔案描述符
用 dup 複製檔案描述符時,新的檔案描述符和舊的檔案描述符共享同一個檔案表表項,示意圖如下:
呼叫 dup 後,兩個描述符指向了相同的檔案表項,而flock 的檔案鎖是加在了檔案表項上,因而如果對 fd0 加鎖那麼 fd1 就會自動持有同一把鎖,釋放鎖時,可以使用這兩個描述符中的任意一個。
通過 fork 產生子程序
通過fork 產生子程序時,子程序完全複製了父程序的資料段和堆疊段,父程序已經開啟的檔案描述符也會被複制,但是檔案表項所在的檔案表是由作業系統統一維護的,並不會由於子程序的產生而發生變化,因而如果父程序打開了一個檔案,假設對應 fd1,那麼在呼叫 fork 後,兩個程序對應的開啟檔案的資料結構如下:
這時父子程序中各有一個開啟的fd,但是它們指向了同一個檔案表項。如果在父程序中已經對 fd0 加了檔案鎖,由於檔案鎖作用於父子程序共享的檔案表項上,這時相當於子程序的fd0 自動擁有了檔案鎖,父程序中的 fd0 和子程序中的fd0 持有的是同一個鎖,因而在釋放鎖時,可以使用父程序或子程序中的任意一個fd。
子程序重複加鎖
上面已經說明,子程序會複製父程序已經開啟的檔案描述符,並且子程序和父程序中的檔案描述符會指向檔案表中的同一個檔案表項。考慮如下情形:在fork 之前,父程序已經對某一檔案描述符加了檔案鎖,fork 產生子程序後,如果子程序對複製的檔案描述符再次用 flock 加鎖,並且鎖的型別與父程序加的並不相同,這裡會發生什麼?
答案就是子程序中新加的鎖會生效,所有指向同一檔案表項的fd 持有的鎖都會變為子程序中新加的鎖。可以認為,子程序新加的鎖起到了修改鎖型別的作用。
execve 函式族中的檔案鎖
在fork 產生子程序後,一般會呼叫 execve 函式族在子程序中執行新的程式。如果在呼叫 execve 之前,子程序中某些開啟的檔案描述符已經持有了檔案鎖,那麼在執行execve 時,如果沒有設定 close-on-exec 標誌,那麼在新的程式中,原本開啟的檔案描述符依然會保持開啟,原本持有的檔案鎖還會繼續持有。
檔案鎖的解除
用 LOCK_UN 解鎖
檔案鎖的解除可以通過將 flock 的 operation 引數設定為 LOCK_UN 常量來實現。這時如果有多個fd 指向同一檔案表項,例如給 fd0 加檔案鎖後,用 dup 複製了fd0 的情況下,用 LOCK_UN 對fd0 解鎖後,所有和 fd0 指向同一檔案表項的 fd 都不再持有檔案鎖。fork 子程序複製父程序檔案描述符的情形也是如此。
關閉檔案時自動解解鎖
對描述符fd加了檔案鎖後,如果沒有顯式使用LOCK_UN 解鎖,在關閉 fd 時,會自動解除其持有的檔案鎖。但是在為 fd 加鎖後如果呼叫 了dup 複製了檔案描述符,這時關閉fd 時的表現和呼叫 LOCK_UN 是不一樣的。
如果未顯式使用 LOCK_UN 解鎖,在關閉檔案描述符後,如果還有其他的fd 指向同一檔案表項,比如之前呼叫了dup 的情形,這時加在檔案表項上的檔案鎖並不會解除,其他指向此檔案表項的檔案描述符依然持有鎖,並且鎖的型別也不會發生變化。
使用fork 產生子程序時同樣如此。父程序和子程序的描述符指向同一檔案表項且已經加了檔案鎖時,如果用 LOCK_UN 將其中一個fd 解鎖,那麼指向同一表項的所有其他fd 都會自動解鎖。但是如果未使用 LOCK_UN 解鎖,只是通過 close(fd) 關閉了某個檔案描述符,那麼指向同一檔案表項的其他描述符,依然會持有原有的鎖。
出於方便考慮,在沒有出現多個fd 指向現一檔案表項的情況下,可以直接使用close(fd) 的預設解鎖功能,而不用顯式的使用LOCK_UN。在有多個 fd 指向同一檔案表項的情形下,如果要完全解鎖,一定要使用 LOCK_UN 解鎖,不能再使用 close(fd) 的預設解鎖功能。
用 fork 驗證以上結論的程式碼如下,讀者可以將下面程式稍作改動,並與本文後面的python 程式配合使用,觀察交替加鎖的情形:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int fd = 0;
int main() {
int i;
char path[]="./file.txt";
extern int errno;
fd=open(path,O_WRONLY|O_CREAT);
if(fd!=-1) {
printf("open file %s. fd:%d.\n",path, fd);
printf("please input a number to lock the file.\n");
scanf("%d",&i);
printf("try lock file:%s...\n", path);
if(flock(fd,LOCK_EX)==0) {
printf("the file was locked.\n");
} else {
printf("the file was not locked.\n");
}
int pid;
if ((pid = fork()) < 0) {
printf("fork failed\n");
exit(0);
} else if (pid == 0) { // child
sleep(5);
//if(flock(fd,LOCK_SH)==0) {
// printf("child add ex success\n");
//} else {
// printf("child add ex failed\n");
//}
if(flock(fd,LOCK_UN)==0) {
printf("child unlock success.\n");
} else {
printf("child unlock fail.\n");
}
sleep(5);
} else { // parent
int pid2=wait(NULL);
printf("end\n");
}
} else {
printf("cannot open file %s/n",path);
printf("errno:%d\n",errno);
printf("errMsg:%s\n",strerror(errno));
}
return 0;
}
用 dup 驗證以上結論的程式碼如下,也可以與 python 示例配合使用,觀察交替加鎖現象:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main() {
int test_close = 1;
int fd,i;
char path[]="/weiboad/work/py_work/file.txt";
extern int errno;
fd = open(path,O_WRONLY|O_CREAT);
if(fd!=-1) {
printf("open file %s .\n",path);
printf("please input a number to lock the file.\n");
scanf("%d",&i);
printf("try lock file:%s...\n", path);
if(flock(fd,LOCK_EX)==0) {
printf("the file was locked.\n");
} else {
printf("the file was not locked.\n");
}
int fd1 = dup(fd);
printf("fd:%d has dup, new fd:%d\n", fd, fd1);
sleep(5);
if (!test_close) {
if(flock(fd,LOCK_UN)==0) {
printf("unlock success\n");
} else {
printf("unlock fail\n");
}
} else {
close(fd);
printf("fd:%d has closed\n", fd);
}
sleep(5);
} else {
printf("cannot open file %s/n",path);
printf("errno:%d\n",errno);
printf("errMsg:%s\n",strerror(errno));
}
printf("end\n");
return 0;
}
常規使用示例
從檔案讀寫示意圖中可以看出,對同一檔案的讀寫即使是完全不相關的兩個程序,也可以使用flock 進行檔案的讀防寫。因而可以認為 flock 是作業系統級別的鎖。為了驗證這一觀點,可以分別用不同的語言對同一檔案進行了鎖定和釋放測試。測試表明,用 flock 對同一檔案進行鎖定,確實是在作業系統層面上全域性生效的。下面分別是C 語言、python、php 對同一檔案的鎖定測試程式碼,可以在同一系統上同時執行其中的任意兩個來驗證檔案鎖對檔案讀寫的全域性保護特性。
C 語言中通過使用者兩次輸入任意整數來控制對檔案的加鎖和解鎖,具體測試程式碼如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main() {
int fd,i;
char path[]="./file.txt";
extern int errno;
fd=open(path,O_WRONLY|O_CREAT);
if(fd!=-1) {
printf("open file %s .\n",path);
printf("please input a number to lock the file.\n");
scanf("%d",&i);
printf("try lock file:%s...\n", path);
if(flock(fd,LOCK_EX)==0) {
printf("the file was locked.\n");
} else {
printf("the file was not locked.\n");
}
printf("please input a number to unlock the file.\n");
scanf("%d",&i);
if(flock(fd,LOCK_UN)==0) {
printf("the file was unlocked.\n");
} else {
printf("the file was not unlocked.\n");
}
close(fd);
} else {
printf("cannot open file %s/n",path);
printf("errno:%d\n",errno);
printf("errMsg:%s\n",strerror(errno));
}
return 0;
python 中對檔案的不斷加鎖和解鎖,當執行其他程序鎖定檔案後,可以看到python 的輸出停止了, 說明檔案鎖被阻塞,具體測試程式碼如下:
import fcntl
import os, time
FILE = "./file.txt"
if not os.path.exists(FILE): # create the counter file if it doesn't exist
file = open(FILE, "w")
file.write("0")
file.close()
for i in range(20):
file = open(FILE, "r+")
print("\ntry acquire lock...")
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
print 'acquire lock success'
counter = int(file.readline()) + 1
file.seek(0)
file.write(str(counter))
print os.getpid(), "=>", counter
time.sleep(2)
file.close() # unlocks the file
print 'release lock'
php 的檔案鎖測試程式碼如下:
<?php
$file_path = "./file.txt";
$fp = fopen($file_path, "r+");
printf("try lock file:$file_path\n");
if (flock($fp, LOCK_EX)) {
printf("acquire lock success\n");
sleep(10);
flock($fp, LOCK_UN); // 釋放鎖定
printf("release lock\n");
} else {
echo "Couldn't get the lock!";
}
fclose($fp);
?>
flock 命令
除了多種語言提供 flock 系統呼叫或函式,linux shell 中也提供了 flock 命令。
flock 命令最大的用途就是實現對 crontab 任務的序列化。在 crontab 任務中,有可能出現某個任務的執行時間超過了 crontab 中為此任務設定的執行週期,這就導致了當前的任務例項還未執行完成,crontab 又啟動了同一任務的另外一個例項,這通常不是使用者所期望的行為。極端情況下,如果某個任務執行異常一直未返回,crontab 不會處理這種情形,會繼續啟動新的例項,而新的例項很可能又會異常,這樣就導致 crontab 對同一任務不斷的啟動新的例項,最終導致系統記憶體被耗盡,影響到整個作業系統的執行。為了防止crontab 任務出現多例項的情況,可以使用 flock 命令將crontab 中任務的週期性執行序列化。
在將corntab 中任務序列化時,flock 通過對一箇中間檔案加檔案鎖來間接實現同一時刻某個任務只有一個例項執行的目標。對應的 crontab 中任務的描述形式如下:
* * * * * flock -xn /tmp/mytest.lock -c 'php /home/fdipzone/php/test.php'
這裡的定時任務是每分鐘執行一次,但是任務中並未直接執行目標命令 ‘php /home/fdipzone/php/test.php’ ,而是將命令作為 flock 的 -c 選項的引數。flock 命令中,-x 表示對檔案加上排他鎖,-n 表示檔案使用非阻塞模式,-c 選項指明加鎖成功後要執行的命令。因而上面flock 命令的整體含義就是:如果對 /tmp/mytest.lock 檔案(如果檔案不存在, flock 命令會自動建立)加鎖成功就執行後面的命令,否則不執行。
假如上面 php 命令要執行2分鐘,而crontab 任務每分鐘就會執行一次,如果當前 php 命令正在執行,說明 flock 已經鎖定了檔案 /tmp/mytest.lock,crontab 到了再次執行任務的時間時,會發現檔案已經被加了鎖。由於設定的是非阻塞模式的檔案鎖,flock 會在加鎖失敗時直接返回,並不執行php 命令,這樣就使 php 命令得以順序執行,crontab 任務就不會出現同時有兩個例項執行的情況了,達到了序列化目的。
結語
flock 在多程序共享檔案時非常有用,避免了用各種“奇技淫巧”來模擬多執行緒中的讀寫鎖,這樣模擬出來的鎖通常會有缺陷。在多程序共享檔案時,強烈建議使用flock 檔案件鎖。一言以蔽之:簡單、易用、高效。
初次使用 flock,如履薄冰,直到把 man page 的每句話都分析一遍並用多種語言嘗試之後,豁然開朗,雖然可能依然有理解不到位的地方,但對於檔案鎖的使用,已經基本熟悉。
每次對技術細節的探索都會有新的收穫,記得一位前同事對我說過:”每次接觸未知的東西,都是你成長最快的時候“。今日感覺,古人誠不我欺!
我就是我,疾馳中的企鵝。
我就是我,不一樣的焰火。
相關推薦
被遺忘的桃源——flock 檔案鎖
緣起 在後臺開發中,隨著多執行緒應用日益增多,人們對多程序的關注也在逐漸減弱。但是在實際應用中,多程序之間的通訊及資源共享,還是會不時的遇到,如果不認真處理,就會出現資料異常,甚至導致系統資源耗盡的情形。今天,我在這裡為大家介紹一下 flock 檔案
linux使用flock檔案鎖解決crontab衝突問題
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
42-使用flock檔案鎖
1. flock函式 flock函式是專門用於實現對檔案加鎖的,與fcntl不同的是,flock系統呼叫最初是源自BSD的,而fcntl則是源自System V,flock是對整個檔案進行加鎖,而fcntl不僅可以對整個檔案加鎖,還可以對檔案部分割槽域加鎖,更加具有靈活性。
linux 檔案鎖flock,lockf,fcntl
1、flock,lockf,fcntl之間區別 先上結論:flock是檔案鎖,鎖的粒度是整個檔案,就是說如果一個程序對一個檔案加了LOCK_EX型別的鎖,別的程序是不能對這個檔案加鎖的。 lockf是對fcntl的封裝,這兩個東西在核心上的實現是一樣的。它們的粒度是位元組,不同的程序可以對相同的檔
PHP檔案鎖解析 flock()
1、普通寫入和讀取b.php寫入$file = 'tt.txt';$fp = fopen($file,'a+b');fwrite($fp,"c");sleep(3);fwrite($fp,"a");c.php讀取$file = 'tt.txt';$fp = fopen($f
每天進步一點點——Linux程式設計中的檔案鎖之flock
無論程式以什麼模式打開了檔案(讀、寫或者讀寫),該檔案上都可以放置一把共享鎖或互斥鎖。在實際操作過程中,引數operation可以指定對應的值將共享鎖轉換成互斥鎖(反之亦然)。將一個共享鎖轉換成互斥鎖,如果另一個程序要獲取該檔案的共享鎖則會阻塞,除非operation引數指定了LOCK_NB標記,即:(LOC
linux C語言實現檔案鎖之flock
一:flock函式特點: 1.flock只能加全域性鎖。 2.當一個程序用flock給一個檔案加鎖時,用另一個程序再給這個檔案加鎖,它會阻塞或者也可以返回加鎖失敗(可以自己設定)。 3.當給一個檔案加fcntl的獨佔鎖後,再給這個檔案加flock的獨佔鎖,其會進入阻塞狀態。
Linux檔案鎖flock,檢查程式是否已經執行
在多個程序同時操作同一份檔案的過程中,很容易導致檔案中的資料混亂,需要鎖操作來保證資料的完整性,這裡介紹的針對檔案的鎖,稱之為“檔案鎖”-flock。 flock,建議性鎖,不具備強制性。一個程序使用flock將檔案鎖住,另一個程序可以直接操作正在被鎖的檔案,修改檔案中的
Linux檔案鎖flock
在多個程序同時操作同一份檔案的過程中,很容易導致檔案中的資料混亂,需要鎖操作來保證資料的完整性,這裡介紹的針對檔案的鎖,稱之為“檔案鎖”-flock。 flock,建議性鎖,不具備強制性。一個程序使用flock將檔案鎖住,另一個程序可以直接操作正在被鎖的檔案,修改檔案中的資料,原因在於flock只是用於檢測
需求管理之被遺忘的需求
實驗室 原因 不同 padding 視野 功能 業務流程 軟件 傳統 先說一個小笑話。有一個生產隊隊長,他對專家說:“如今我們生產隊的地越來越多,牛越來越忙只是來了。我想要這麽一種牛,他吃的草和普通牛一樣多,可是幹的活是普通牛的十倍。”專家說:“這種牛是能夠
oracle 記錄被另一個用戶鎖住
語句 order user ora rac mode 表名 order by 用戶 第一步:查詢處用戶,被鎖表名,sessionID select b.owner,b.object_name,l.session_id,l.locked_modefrom v$locked_
linux中的檔案鎖(勸告性上鎖和強制性上鎖)
上午在看UNP卷二這一節的時候及其想睡覺,就草草了事,夜晚沒有事情幹,就來找找部落格看看這兩個鎖到底是怎麼回事吧! 參考文章:https://www.ibm.com/developerworks/cn/linux/l-cn-filelock/index.html 背景知識:在早期的
磁碟被格式化了的檔案尋回辦法
格式化後硬碟只剩下一點格式化產生的隱藏檔案。不過如果馬上停止寫入新的檔案,那麼絕大部分檔案都可以恢復的。具體恢復的方法也很簡單。 工具/軟體:AuroraDataRecovery 步驟1:先下載並解壓程式執行後,直接雙擊需要恢復的分割槽,然後右擊軟體圖示選擇
Python佇列與多執行緒及檔案鎖
佇列實現生產-多執行緒消費 先看程式碼 # -*- coding: utf-8 -*- import queue import threading mu = threading.Lock() class Producer(threading.Thread): def __init__(
C語言入坑指南-被遺忘的初始化
前言 什麼是初始化?為什麼要初始化?靜態變數和區域性變數的初始化又有什麼區別?實際應用中應該怎麼做?本文將一一回答這些問題。 什麼是初始化 初始化指的是對資料物件或者變數賦予初始值。例如: int value = 8; //宣告整型變數並初始化為8int&nbs
PHP 利用檔案鎖處理高併發
利用 flock()函式對檔案進行加鎖(排它鎖),實現併發按序進行。 flock(file,lock,block)有三個引數。 file : 已經開啟的檔案 lock : 鎖的型別 LOCK_SH : 共享鎖定(讀鎖) LOCK_EX : 獨佔鎖定(排它鎖,寫鎖
Oracle查詢被鎖定表以及解鎖
1、查詢被鎖資訊 SELECT object_name, machine, s.sid, s.serial# FROM gv$locked_object l, dba_objects o, gv$session s WHERE l.object_id = o.obj
蘋果應用稽核被拒,二進位制檔案被拒絕,怎麼回事?
蘋果應用稽核被拒,二進位制檔案被拒絕,怎麼回事? Hello, If you would like to appeal this rejection to the App Review Board, you must do so within 14 calendar days. Othe
fcntl與檔案鎖【轉】
第一節Unix支援的檔案鎖技術介紹 Unix系統允許多個程序同時對一個檔案進行讀寫,雖然每一個read或write呼叫本身是原子的,但核心在兩個讀寫操作之間並沒有加以同步,因此當一個程序多次呼叫read來讀檔案時,其它程序有可能在兩次read之間改變該檔案,造成檔案資料
那迷人的被遺忘的語言——Prolog
在進入正題之前,我們先一起思考一個問題:當我們在程式設計時,我們在做什麼? 看到這個問題,有些同學可能會第一時間要回答: 在聽音樂 在打字 在發呆 在裝作很忙的樣子 …… 呃,我不是那個意思,說認真的:當我們在程式設計時,我們在做什麼? 我們在把所想的「解決方案