Chinaunix首页 | 论坛 | 博客
  • 博客访问: 677552
  • 博文数量: 77
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1173
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-16 11:20
个人简介

将技术做到极致...

文章分类

全部博文(77)

文章存档

2019年(3)

2015年(27)

2014年(47)

分类: LINUX

2014-06-24 15:56:38

Linux下文件锁操作主要是通过以下两个API接口来完成的。

    #include    

    int flock(int fd, int operation);    
或者

    #include    

    #include    

    int fcntl(int fd, int cmd);  

    int fcntl(int fd, int cmd, long arg);  

    int fcntl(int fd, int cmd, struct flock *lock);  
注:前者主要用于对整个文件的锁操作,后者可以对文件的部分内容进行锁操作

Linux应用程序编程时应该注意以下几点:

1)文件锁是针对整个文件还是文件的部分内容。

2)进程级文件句柄关闭将会导致文件锁释放。

3)文件内容修改需要注意到glibc的缓冲机制,及时同步数据。

4)flock锁inode,fcntl锁文件描述符,因此flock不支持NFS,兼容性需要注意。

这里将给出进程级和线程级文件锁demo code供参考。

进程级文件锁demo:

#include
#include
#include
#include
#include

#define TEST_FOPEN

int main(int argc, char *argv[])
{
    /* l_type   l_whence  l_start  l_len  l_pid   */
    struct flock fl = {F_WRLCK, SEEK_SET,   0,      0,     0 };
    int fd;

#ifdef TEST_FOPEN
 FILE *file = NULL;
#endif /* TEST_FOPEN */

    fl.l_pid = getpid();

    if (argc > 1)
        fl.l_type = F_RDLCK;

 while(1)
 {
#ifdef TEST_FOPEN
    if ((file = fopen("lockdemo.c", "rw+")) == NULL) {
        perror("fopen");
        exit(1);
    }
#else
    if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
        perror("open");
        exit(1);
    }
#endif /* TEST_FOPEN */
  printf("Press to try to get lock: ");
  getchar();
  printf("Trying to get lock...");

 #ifdef TEST_FOPEN
  fd = fileno(file);
 #endif /* TEST_FOPEN */

  fl.l_type = F_WRLCK;  /* set to lock same region */
  if (fcntl(fd, F_SETLKW, &fl) == -1) {
   perror("fcntl");
   exit(1);
  }

  printf("got lock\n");
  printf("Press to release lock: ");
  getchar();

  fl.l_type = F_UNLCK;  /* set to unlock same region */

  if (fcntl(fd, F_SETLK, &fl) == -1) {
   perror("fcntl");
   exit(1);
  }

  printf("Unlocked.\n");
#ifdef TEST_FOPEN
 fclose(file);
#else
    close(fd);
#endif /* TEST_FOPEN */
 }

    return 0;
}

运行结果:




线程级文件锁demo:

#include
#include
#include
#include
#include
#include

#define TEST_FOPEN
#define TEST_FLOCK

void* thread_flock(void* ptr)
{
    /* l_type   l_whence  l_start  l_len  l_pid   */
    struct flock fl = {F_WRLCK, SEEK_SET,   0,      0,     0 };
    int fd;

 int ith = *((int *)ptr);

#ifdef TEST_FOPEN
 FILE *file = NULL;
#endif /* TEST_FOPEN */

    fl.l_pid = getpid();

 while(1)
 {
#ifdef TEST_FOPEN
    if ((file = fopen("lockdemo.c", "rw+")) == NULL) {
        perror("fopen");
        exit(1);
    }
#else
    if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
        perror("open");
        exit(1);
    }
#endif /* TEST_FOPEN */

#ifdef TEST_FOPEN
  fd = fileno(file);
#endif /* TEST_FOPEN */

#ifdef TEST_FLOCK
  flock(fd, LOCK_EX);
#else
  fl.l_type = F_WRLCK;  /* set to lock same region */
  if (fcntl(fd, F_SETLKW, &fl) == -1) {
   perror("fcntl");
   exit(1);
  }
#endif /* TEST_FLOCK */

  printf("[%d] %d --> got lock\n", ith, fd);
  sleep(ith);

#ifdef TEST_FLOCK
  flock(fd, LOCK_UN);
#else
  fl.l_type = F_UNLCK;  /* set to unlock same region */

  if (fcntl(fd, F_SETLKW, &fl) == -1) {
   perror("fcntl");
   exit(1);
  }
#endif /* TEST_FLOCK */

  printf("[%d] %d--> Unlocked.\n", ith, fd);
#ifdef TEST_FOPEN
 fclose(file);
#else
    close(fd);
#endif /* TEST_FOPEN */

  sleep(2);
 }
}

int main(int argc, char *argv[])
{
 int time1, time2;

 pthread_t pid1,pid2;

 time1 = 1;
 pthread_create(&pid1, NULL, &thread_flock, &time1);

 time2 = 3;
 pthread_create(&pid2, NULL, &thread_flock, &time2);

 while(1)
  sleep(10);

    return 0;
}
 

运行结果:

阅读(2057) | 评论(0) | 转发(0) |
0

上一篇:动态库Makefile模板

下一篇:xargs命令使用

给主人留下些什么吧!~~