系統(tǒng)調(diào)用fcntl
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, struct flock *lock );
參數(shù):
fd
:文件描述符
cmd
:F_GETLK, F_SETLK or F_SETLKW
lock
:按照如下規(guī)則填寫勺卢,可以達(dá)到相應(yīng)效果
F_GETLK, F_SETLK and F_SETLKW are used to acquire, release, and test for the existence of record locks (also known as file-segment or file-region
locks). The third argument, lock, is a pointer to a structure that has at least the following fields (in unspecified order).
struct flock {
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock
(F_GETLK only) */
...
};
文件鎖的封裝
filelock.h:
#ifndef _FILE_LOCK_H
#define _FILE_LOCK_H
int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len);
int File_ReadLck(int fd, off_t offset, int whence, off_t len);
int File_WriteLck(int fd, off_t offset, int whence, off_t len);
int File_ReadLckW(int fd, off_t offset, int whence, off_t len);
int File_WriteLckW(int fd, off_t offset, int whence, off_t len);
int File_Unlock(int fd, off_t offset, int whence, off_t len);
#endif
filelock.c:
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include "filelock.h"
int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;
lock.l_type = type;
lock.l_start = offset;
lock.l_whence = whence;
lock.l_len = len;
return (fcntl(fd, cmd, &lock));
}
int File_ReadLck(int fd, off_t offset, int whence, off_t len)
{
return lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len);
}
int File_WriteLck(int fd, off_t offset, int whence, off_t len)
{
return lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len);
}
int File_ReadLckW(int fd, off_t offset, int whence, off_t len)
{
return lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len);
}
int File_WriteLckW(int fd, off_t offset, int whence, off_t len)
{
return lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len);
}
int File_Unlock(int fd, off_t offset, int whence, off_t len)
{
return lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len);
}
例程
#include <stdio.h>
#include <fcntl.h>
#include "filelock.h"
int main(void)
{
int fd = 0;
pid_t pid = 0;
fd = open("tmp", O_RDWR|O_CREAT|O_TRUNC, 0666);
unlink("tmp");
pid = fork();
if(0 == pid)
{
while(1)
{
File_WriteLckW(fd, 0, SEEK_SET, 1);
printf("====> child process\n\n");
usleep(5000000);
File_Unlock(fd, 0, SEEK_SET, 1);
usleep(500000);
}
}
while(1)
{
File_WriteLckW(fd, 0, SEEK_SET, 1);
printf("#### parent process\n\n");
usleep(5000000);
File_Unlock(fd, 0, SEEK_SET, 1);
usleep(500000);
}
return 0;
}
文件鎖的用法:
- 不同的對(duì)象訪問同一文件,可以使用文件鎖達(dá)到讀寫同步谢肾,不會(huì)導(dǎo)致文件寫入混亂。
- 進(jìn)程間訪問同一資源悦析,使用文件鎖作為進(jìn)程間的鎖達(dá)到訪問同步开财;
用法
:創(chuàng)建一個(gè)空文件,并使用文件的第一字節(jié)(無需存在)作為鎖字節(jié)惹悄,然后unlink文件春叫;獲取資源之前,先獲取該字節(jié)的寫鎖泣港;釋放資源時(shí)暂殖,對(duì)該字節(jié)解鎖。記錄鎖的一個(gè)優(yōu)點(diǎn)是:持有鎖的進(jìn)程終止退出時(shí)当纱,內(nèi)核會(huì)自動(dòng)釋放該鎖呛每,所以進(jìn)程間就不會(huì)因?yàn)檫M(jìn)程崩潰導(dǎo)致死鎖。