Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2888796
  • 博文数量: 348
  • 博客积分: 2907
  • 博客等级: 中校
  • 技术积分: 2272
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-12 09:16
个人简介

专注 K8S研究

文章分类

全部博文(348)

文章存档

2019年(22)

2018年(57)

2016年(2)

2015年(27)

2014年(33)

2013年(190)

2011年(3)

2010年(14)

分类: LINUX

2013-07-01 00:53:24

原文地址:Mysql 常用命令 转 作者:Aquester

  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. // 10) flock锁不会被fork出的子进程继承,对于dup得到的fd是递归的,对于open得到的fd是非递归的
  12. // 11) fcntl锁会被fork出的子进程继承,对于open得到的fd是递归的
  13. // 12) flock和file table entry相关,而不是fd
  14. // 13) flock和fcntl锁互不影响,可同时时对同一个文件上锁,而不会死锁
  15. #include <fcntl.h>
  16. #include <pthread.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <sys/file.h>
  23. #include <sys/wait.h>
  24. #include <unistd.h>
  25. // 查看锁信息: cat /proc/locks
  26. // 编译方法: g++ -g -o file_lock file_lock.cpp -pthread -DX=3 -DZ=2
  27. // 宏X控制是使用flock、lockf还是fcntl文件锁,值为1使用flock,值为2使用lockf,值为3使用fcntl
  28. // 宏Z控制是多线程还是多进程,值为1为多线程模式,值为2为多进程模式

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

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

  48.     if (-1 == flock(fd, LOCK_EX))
  49.     {
  50.         printf("flock error: %m\n");
  51.         close(fd);
  52.         exit(1);
  53.     }
  54.     return fd;
  55. }

  56. void unlock(int fd)
  57. {
  58.     flock(fd, LOCK_UN);
  59.     close(fd);
  60. }

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

  70.     lseek(fd,0L,0);
  71.     if (-1 == lockf(fd, F_LOCK, 0L))
  72.     {
  73.         printf("lockf error: %m\n");
  74.         exit(1);
  75.     }
  76.     return fd;
  77. }

  78. void unlock(int fd)
  79. {
  80.     lseek(fd,0L,0);
  81.     lockf(fd, F_ULOCK, 0);
  82.     close(fd);
  83. }

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

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

  105.     return fd;
  106. }

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

  120. void* thread1(void* param)
  121. {
  122.     printf("[%u][%s] to sleep 2\n", pthread_self(), now().c_str());
  123.     sleep(2);

  124.     printf("[%u][%s] to lock\n", pthread_self(), now().c_str());
  125.     const char* file = (const char*)param;
  126.     int fd = lock(file);
  127.     printf("[%u][%s] locked\n", pthread_self(), now().c_str());

  128.     unlock(fd);
  129.     printf("[%u][%s] unkock and exit\n", pthread_self(), now().c_str());
  130.     return NULL;
  131. }

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

  138.     sleep(6);
  139.     unlock(fd);
  140.     printf("[%u][%s] unkock and exit\n", pthread_self(), now().c_str());
  141.     return NULL;
  142. }

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

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

  155.     pthread_t th1, th2;
  156.     pthread_create(&th1, NULL, thread1, const_cast<char*>(file));
  157.     pthread_create(&th2, NULL, thread2, const_cast<char*>(file));

  158.     pthread_join(th1, NULL);
  159.     pthread_join(th2, NULL);

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

  162.     pid_t pid1 = fork();
  163.     if (0 == pid1)
  164.     {
  165.         printf("[%u][%s] to sleep 2\n", getpid(), now().c_str());
  166.         sleep(2);

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

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

  180.         sleep(6);
  181.         unlock(fd);
  182.         printf("[%u][%s] unkock and exit\n", getpid(), now().c_str());
  183.         exit(0);
  184.     }

  185.     waitpid(pid1, NULL, 0);
  186.     waitpid(pid2, NULL, 0);
  187. #endif

  188.     return 0;
  189. }


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