Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1347054
  • 博文数量: 244
  • 博客积分: 1039
  • 博客等级: 少尉
  • 技术积分: 1562
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-06 09:40
文章分类

全部博文(244)

文章存档

2021年(2)

2019年(6)

2018年(2)

2014年(1)

2013年(187)

2012年(47)

分类: LINUX

2013-05-22 16:03:17

x.zip

  1. // 文件锁flock、lockf和fcntl区别测试程序:
  2. // 1) flock是系统调用,为System V锁
  3. // 2) fcntl是系统调用,lockf是基于fcntl实现的libc库函数,为posix锁
  4. // 3) flock可以同时用于多线程和多进程互斥(x86 Linux验证)
  5. // 4) 而lockf和fcntl只能用于多进程
  6. // 5) 对于NFS,只能使用fcntl,而flock只能用于本地文件系统
  7. // 6) flock只是建议性锁
  8. // 7) fcntl可以实现强制性锁
  9. // 8) flock只能对整个文件加锁
  10. // 9) fcntl和lockf可以只加锁文件的指定部分
  11. #include <fcntl.h>
  12. #include <pthread.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <sys/file.h>
  19. #include <sys/wait.h>
  20. #include <unistd.h>
  21. // 查看锁信息: cat /proc/locks
  22. // 编译方法: g++ -g -o x x.cpp -pthread -DX=3 -DZ=2
  23. // 宏X控制是使用flock、lockf还是fcntl文件锁,值为1使用flock,值为2使用lockf,值为3使用fcntl
  24. // 宏Z控制是多线程还是多进程,值为1为多线程模式,值为2为多进程模式

  25. // 取当前时间,但不包括日期部分
  26. std::string now()
  27. {
  28.     time_t t = time(NULL);
  29.     struct tm tm;
  30.     localtime_r(&t, &tm);
  31.     char buf[sizeof("22:49:22")];
  32.     snprintf(buf, sizeof(buf), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
  33.     return buf;
  34. }

  35. #if X==1 // flock
  36. int lock(const char* file)
  37. {
  38.     int fd = open(file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  39.     if (-1 == fd)
  40.     {
  41.         printf("open error: %m\n");
  42.         exit(1);
  43.     }

  44.     if (-1 == flock(fd, LOCK_EX))
  45.     {
  46.         printf("flock error: %m\n");
  47.         close(fd);
  48.         exit(1);
  49.     }
  50.     return fd;
  51. }

  52. void unlock(int fd)
  53. {
  54.     flock(fd, LOCK_UN);
  55.     close(fd);
  56. }

  57. #elif X == 2 // lockf
  58. int lock(const char* file)
  59. {
  60.     int fd = open(file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  61.     if (-1 == fd)
  62.     {
  63.         printf("open error: %m\n");
  64.         exit(1);
  65.     }

  66.     lseek(fd,0L,0);
  67.     if (-1 == lockf(fd, F_LOCK, 0L))
  68.     {
  69.         printf("lockf error: %m\n");
  70.         exit(1);
  71.     }
  72.     return fd;
  73. }

  74. void unlock(int fd)
  75. {
  76.     lseek(fd,0L,0);
  77.     lockf(fd, F_ULOCK, 0);
  78.     close(fd);
  79. }

  80. #elif X==3 // fcntl
  81. int lock(const char* file)
  82. {
  83.     int fd = open(file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  84.     if (-1 == fd)
  85.     {
  86.         printf("open error: %m\n");
  87.         exit(1);
  88.     }

  89.     struct flock f;
  90.     f.l_whence = SEEK_SET;
  91.     f.l_start = 0;
  92.     f.l_len = 0;
  93.     f.l_type = F_WRLCK;
  94.     f.l_pid = getpid();
  95.     lseek(fd,0L,0);
  96.     if (-1 == fcntl(fd, F_SETLKW, &f))
  97.     {
  98.         printf("fcntl error: %m\n");
  99.         exit(1);
  100.     }

  101.     return fd;
  102. }

  103. void unlock(int fd)
  104. {
  105.     struct flock f;
  106.     f.l_whence = SEEK_SET;
  107.     f.l_start = 0;
  108.     f.l_len = 0;
  109.     f.l_type = F_UNLCK;
  110.     f.l_pid = getpid();
  111.     lseek(fd,0L,0);
  112.     fcntl(fd, F_SETLKW, &f);
  113.     close(fd);
  114. }
  115. #endif

  116. void* thread1(void* param)
  117. {
  118.     printf("[%u][%s] to sleep 2\n", pthread_self(), now().c_str());
  119.     sleep(2);

  120.     printf("[%u][%s] to lock\n", pthread_self(), now().c_str());
  121.     const char* file = (const char*)param;
  122.     int fd = lock(file);
  123.     printf("[%u][%s] locked\n", pthread_self(), now().c_str());

  124.     unlock(fd);
  125.     printf("[%u][%s] unkock and exit\n", pthread_self(), now().c_str());
  126.     return NULL;
  127. }

  128. void* thread2(void* param)
  129. {
  130.     printf("[%u][%s] to lock\n", pthread_self(), now().c_str());
  131.     const char* file = (const char*)param;
  132.     int fd = lock(file);
  133.     printf("[%u][%s] locked and sleep 6\n", pthread_self(), now().c_str());

  134.     sleep(6);
  135.     unlock(fd);
  136.     printf("[%u][%s] unkock and exit\n", pthread_self(), now().c_str());
  137.     return NULL;
  138. }

  139. int main(int argc, char* argv[])
  140. {
  141.     const char* file = "abc";
  142. #if X==1
  143.     printf("flock mode\n");
  144. #elif X==2
  145.     printf("lockf mode\n");
  146. #elif X==3
  147.     printf("fcntl mode\n");
  148. #endif

  149. #if Z==1 // 多线程模式
  150.     printf("thread mode\n");

  151.     pthread_t th1, th2;
  152.     pthread_create(&th1, NULL, thread1, const_cast<char*>(file));
  153.     pthread_create(&th2, NULL, thread2, const_cast<char*>(file));

  154.     pthread_join(th1, NULL);
  155.     pthread_join(th2, NULL);

  156. #else // 多进程模式
  157.     printf("process mode\n");

  158.     pid_t pid1 = fork();
  159.     if (0 == pid1)
  160.     {
  161.         printf("[%u][%s] to sleep 2\n", getpid(), now().c_str());
  162.         sleep(2);

  163.         printf("[%u][%s] to lock\n", getpid(), now().c_str());
  164.         int fd = lock(file);
  165.         printf("[%u][%s] locked\n", getpid(), now().c_str());
  166.         unlock(fd);
  167.         printf("[%u][%s] unkock and exit\n", getpid(), now().c_str());
  168.         exit(0);
  169.     }

  170.     pid_t pid2 = fork();
  171.     if (0 == pid2)
  172.     {
  173.         printf("[%u][%s] to lock\n", getpid(), now().c_str());
  174.         int fd = lock(file);
  175.         printf("[%u][%s] locked and sleep 6\n", getpid(), now().c_str());

  176.         sleep(6);
  177.         unlock(fd);
  178.         printf("[%u][%s] unkock and exit\n", getpid(), now().c_str());
  179.         exit(0);
  180.     }

  181.     waitpid(pid1, NULL, 0);
  182.     waitpid(pid2, NULL, 0);
  183. #endif

  184.     return 0;
  185. }


阅读(775) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~