Posted on 2008-03-28 10:18
王大头 阅读(1464)
评论(0) 编辑 收藏 引用
看了一天资料,终于把fcntl的F_GETLK,F_SETLK,F_SETLKW弄的差不多明白了。
fcntl函数原型:
#include <fcntl.h>
int fcntl(int fildes, int cmd, ... /* arg */);
支持的cmd:
cmd:
F_DUPFD
F_GETFD
F_SETFD
F_GETFL
F_SETFL
F_GETLK
F_SETLK
F_SETLKW
F_GETOWN
F_SETOWN
flock结构:
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
_T_OFF_T l_start; /* starting offset relative to l_whence */
_T_OFF_T l_len; /* len == 0 means "until end of file" */
pid_t l_pid; /* Process ID of the process holding the
lock, returned with F_GETLK */
};
自己写了两个例程:
setlk.c
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
struct flock *do_lock()
{
static struct flock do_flk;
do_flk.l_type = F_WRLCK;
do_flk.l_whence = SEEK_SET;
do_flk.l_start = 0;
do_flk.l_len = 0;
do_flk.l_pid = getpid();
return(&do_flk);
}
struct flock *un_lock()
{
static struct flock un_flk;
un_flk.l_type = F_UNLCK;
un_flk.l_whence = SEEK_SET;
un_flk.l_start = 0;
un_flk.l_len = 0;
un_flk.l_pid = getpid();
return(&un_flk);
}
int main()
{
int fd;
int ret;
struct flock *flk;
fd=open("lock.file", O_WRONLY);
flk = do_lock();
ret = fcntl(fd, F_SETLKW, flk);
printf("fd=[%d],ret=[%d],errno=[%d],strerror=[%s]\n", fd, ret, errno, strerror(errno));
sleep(60);
flk = un_lock();
close(fd);
ret = fcntl(fd, F_SETLK, flk);
printf("fd=[%d],ret=[%d],errno=[%d],strerror=[%s]\n", fd, ret, errno, strerror(errno));
}
getlk.c
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
struct flock *get_lock()
{
static struct flock get_flk;
get_flk.l_type = F_UNLCK;
get_flk.l_whence = SEEK_SET;
get_flk.l_start = 0;
get_flk.l_len = 0;
get_flk.l_pid = 0;
return(&get_flk);
}
int main()
{
int fd;
int ret;
struct flock *flk;
fd=open("lock.file", O_WRONLY);
flk = get_lock();
ret = fcntl(fd, F_GETLK, flk);
close(fd);
printf("fd=[%d],ret=[%d],errno=[%d],strerror=[%s]\n", fd, ret, errno, strerror(errno));
printf("l_type=[%d],l_whence=[%d],l_start=[%d],l_len=[%d],l_pid=[%d],pid=[%d]\n",\
flk->l_type,flk->l_whence,flk->l_start,flk->l_len,flk->l_pid,getpid());
}
setlk执行结果:
bill1:[/billdata01/wangc/lock]$setlk
fd=[3],ret=[0],errno=[0],strerror=[Error 0]
getlk执行结果:
bill1:[/billdata01/wangc/lock]$getlk
fd=[3],ret=[0],errno=[0],strerror=[Error 0]
l_type=[2],l_whence=[0],l_start=[0],l_len=[0],l_pid=[6501],pid=[6511]
fd关闭之后自动解锁,unlock的时候可以直接close(fd)。
判断F_SETLK,F_SETLKW执行是否成功可以直接看fcntl返回值。
判断F_GETLK执行结果,就要看flock成员是否被修改,可以判断l_type是否被修改,也可以判断pid是否是预设值。