檔案鎖

wzm10455發表於2013-01-21

為了保證檔案操作的正確性和準確性,引入了檔案鎖這個概念。

檔案鎖:
1.讀鎖(共享鎖)
  當一個程式對某個檔案加了一把讀鎖後,其他的任何程式可以對此檔案繼續加讀鎖,但是不能加寫鎖,如果強制加讀鎖,則堵塞
 2.寫鎖(獨享鎖)
  當一個程式對某個檔案加了一把寫鎖後,其它程式不能對此檔案加鎖(包括讀鎖和寫鎖)。



fcntl(檔案描述詞操作)
相關函式
open,flock
表標頭檔案
#include<unistd.h>
#include<fcntl.h>
定義函式
int fcntl(int fd , int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock * lock);
函式說明
fcntl()用來操作檔案描述詞的一些特性。引數fd代表欲設定的檔案描述詞,引數cmd代表欲操作的指令。
有以下幾種情況:
F_DUPFD用來查詢大於或等於引數arg的最小且仍未使用的檔案描述詞,並且複製引數fd的檔案描述詞。執行成功則返回新複製的檔案描述詞。請參考dup2()。F_GETFD取得close-on-exec旗標。若此旗標的FD_CLOEXEC位為0,代表在呼叫exec()相關函式時檔案將不會關閉。
F_SETFD 設定close-on-exec 旗標。該旗標以引數arg 的FD_CLOEXEC位決定。
F_GETFL 取得檔案描述詞狀態旗標,此旗標為open()的引數flags。
F_SETFL 設定檔案描述詞狀態旗標,引數arg為新旗標,但只允許O_APPEND、O_NONBLOCK和O_ASYNC位的改變,其他位的改變將不受影響。
F_GETLK 取得檔案鎖定的狀態。
F_SETLK 設定檔案鎖定的狀態。此時flcok 結構的l_type 值必須是F_RDLCK、F_WRLCK或F_UNLCK。如果無法建立鎖定,則返回-1,錯誤程式碼為EACCES 或EAGAIN。
F_SETLKW F_SETLK 作用相同,但是無法建立鎖定時,此呼叫會一直等到鎖定動作成功為止。若在等待鎖定的過程中被訊號中斷時,會立即返回-1,錯誤程式碼為EINTR。引數lock指標為flock 結構指標,定義如下
struct flcok
{
short int l_type; /* 鎖定的狀態*/
short int l_whence;/*決定l_start位置*/
off_t l_start; /*鎖定區域的開頭位置*/
off_t l_len; /*鎖定區域的大小*/
pid_t l_pid; /*鎖定動作的程式*/
};
l_type 有三種狀態:
F_RDLCK 建立一個供讀取用的鎖定
F_WRLCK 建立一個供寫入用的鎖定
F_UNLCK 刪除之前建立的鎖定
l_whence 也有三種方式:
SEEK_SET 以檔案開頭為鎖定的起始位置。
SEEK_CUR 以目前檔案讀寫位置為鎖定的起始位置
SEEK_END 以檔案結尾為鎖定的起始位置。
返回值
成功則返回0,若有錯誤則返回-1,錯誤原因存於errno.
 
   
   
   
   
   
   
   
 

寫鎖:

#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
int flie_lock(int fd,short int lock_type)
{
    struct flock lock;//鎖下面的每個內容都需要填充

    lock.l_type=lock_type;
    lock.l_whence=SEEK_SET;
    lock.l_start=0;
    lock.l_len=0;
    lock.l_pid=getpid();

    if(fcntl(fd,F_SETLK,&lock)<0)//如果這裡F_SETLK改成F_SETLKW,則由堵塞變成非堵塞
    {
        perror("fcntl error");
        return -1;
    }
    return 0;
}
int main(void)
{
    int fd;
    char buf[20]="hello!";
    fd=open("./TXT",O_CREAT|O_WRONLY,0666);
    if(-1==fd)
    {
        perror("open error");
        return -1;
    }
    printf("write before!\n");
    flie_lock(fd,F_WRLCK);//加的是寫鎖
    printf("write after!\n");
    if(write(fd,buf,20)<0)
    {
        perror("write error");
        return -1;
    }
    while(1);
    flie_lock(fd,F_UNLCK);//解鎖
    return 0;
}
讀鎖:

#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>

int file_lock(int fd,short int lock_type)
{
	struct flock lock;

	lock.l_type=lock_type;
	lock.l_whence=SEEK_SET;
	lock.l_start=0;
	lock.l_len=0;
	lock.l_pid=getpid();

	if(fcntl(fd,F_SETLKW,&lock)<0)
	{
		perror("fcntl error");
		return -1;
	}
	return 0;
}

int main()
{
	int fd;
	char buf[20];
	fd=open("./TXT",O_CREAT|O_RDWR,0666);
	if(-1==fd)
	{
		perror("open error");
		return -1;
	}

	printf("read before!\n");
	file_lock(fd,F_RDLCK);
	printf("read after!\n");
	if(read(fd,buf,20)<0)
	{
		perror("write error");
		return -1;
	}
	while(1);
	file_lock(fd,F_UNLCK);
}





相關文章