千家信息网

unix 高级IO 文件锁

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,1. 注意fcntl()参数cmd 的正确使用F_GETFL 用于测试锁使用F_SETFL 无阻塞设置锁 fcntl()会尝试几次后,如果失败直接返回-1F_SETLKW 阻塞设置锁 fcntl()会
千家信息网最后更新 2025年01月31日unix 高级IO 文件锁

1. 注意fcntl()参数cmd 的正确使用

F_GETFL 用于测试锁使用

F_SETFL 无阻塞设置锁 fcntl()会尝试几次后,如果失败直接返回-1

F_SETLKW 阻塞设置锁 fcntl()会尝试后,如果失败会被系统挂起来,直到收到解锁的信号再去执行

2. 测试锁的时候 struct flock lock结构体成员 中的l_stype 需要设置为F_WRLCK 其它F_UNLCK,F_RDLCK会有问题

3.struct flock lock 成员使用

测试或锁 整个文件怎样设置

l_whence = SEEK_SET

l_start = 0;

l_len = 0; 如果l_len为0 表示 从start 开始一直到文件最后EOF

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) */

...

};


5.程序自己测试自己的锁, 测试后肯定是无锁状态

6.程序如果设置的两个区间 连续而且锁的性质一样,系统会自动地将两个锁合并成一个锁

7.更多可以参考以下牛人

http://zhuyunxiang.blog.51cto.com/653596/132548



执行结果:

在另一个终端执行


main.c

  1. #include"setlock.h"
  2. #include<stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. int main(void)
  7. {
  8. int fd = open("./src", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IXOTH);
  9. check_lock(fd,0,10);
  10. check_lock(fd,11,20);
  11. set_read_lock(fd,0,10);
  12. set_write_lock(fd,11,20);
  13. sleep(15);
  14. unlock(fd,0,10);
  15. unlock(fd,11,20);
  16. return 0;
  17. }

setlock.h

  1. #ifndef SETLOCK_H
  2. #define SETLOCK_H
  3. void check_lock(int fd,int start,int len);
  4. void unlock(int fd,int start,int len);
  5. void set_read_lock(int fd,int start,int len);
  6. void set_write_lock(int fd,int start,int len);
  7. #endif // end SETLOCK_H

setlock.c

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include <sys/types.h>
  6. #include<stdbool.h>
  7. void check_lock(int fd,int start,int len)
  8. {
  9. struct flock lock;
  10. lock.l_type = F_WRLCK;
  11. lock.l_start = start;
  12. lock.l_whence = SEEK_SET;
  13. lock.l_len = start;
  14. printf("check_lock------\n");
  15. if((fcntl(fd, F_GETLK, &lock)) == -1)
  16. {
  17. printf("1-check_lock: fcntl error\n");
  18. exit(1);
  19. }
  20. switch(lock.l_type)
  21. {
  22. case F_RDLCK:
  23. {
  24. printf("[%d]:FRDLCK From %d To %d\n", lock.l_pid, start, len);
  25. break;
  26. }
  27. case F_WRLCK:
  28. {
  29. printf("[%d]:F_WRLCK From %d To %d\n", lock.l_pid, start, len);
  30. break;
  31. }
  32. case F_UNLCK:
  33. {
  34. printf("F_UNLCK\n");
  35. break;
  36. }
  37. default:
  38. {
  39. printf("2-check_lock: fcntl error");
  40. break;
  41. }
  42. }
  43. }
  44. void set_read_lock(int fd,int start,int len)
  45. {
  46. printf("set_read_lock------\n");
  47. struct flock lock;
  48. lock.l_type = F_RDLCK;
  49. lock.l_start = 0;
  50. lock.l_whence = SEEK_SET;
  51. lock.l_len = 0;
  52. if((fcntl(fd, F_SETLKW, &lock)) == -1)
  53. {
  54. printf("set_lock: fcntl error\n");
  55. exit(1);
  56. }
  57. else
  58. {
  59. printf("[%d] set readlock From %d To %d\n", getpid(), start, len);
  60. }
  61. }
  62. void set_write_lock(int fd,int start,int len)
  63. {
  64. printf("set_write_lock------\n");
  65. struct flock lock;
  66. lock.l_type = F_WRLCK;
  67. lock.l_start = start;
  68. lock.l_whence = SEEK_SET;
  69. lock.l_len = len;
  70. if((fcntl(fd, F_SETLKW, &lock)) == -1)
  71. {
  72. printf("set_lock: fcntl error\n");
  73. exit(1);
  74. }
  75. else
  76. {
  77. printf("[%d] set writelock From %d To %d\n", getpid(), start, len);
  78. }
  79. }
  80. bool unlock(int fd,int start,int len)
  81. {
  82. printf("unlock------\n");
  83. struct flock lock;
  84. lock.l_type = F_UNLCK;
  85. lock.l_start = start;
  86. lock.l_whence = SEEK_SET;
  87. lock.l_len = len;
  88. if((fcntl(fd, F_SETLK, &lock)) == -1)
  89. {
  90. printf("1-unlock: fcntl error\n");
  91. exit(1);
  92. }
  93. printf("unlock [%d~%d]\n",start,len);
  94. }

makefile

  1. srcs=$(wildcard *.c)
  2. objs =$(patsubst %c,%o,$(srcs))
  3. CC = gcc
  4. Target = main
  5. ####################
  6. .PHONY: all clean # command: make all or make clean
  7. clean:
  8. rm -f $(obj) main *~ *gch
  9. ###################
  10. all: $(Target)
  11. $(Target):$(objs)
  12. $(CC) -o $@ $^
  13. main.o:main.c
  14. $(CC) -c $<
  15. tool0.o:tool0.c
  16. $(CC) -c $<
  17. tool1.o:tool1.c
  18. $(CC) -c $<

附件:http://down.51cto.com/data/2362130
0