鱼C论坛

 找回密码
 立即注册
查看: 3541|回复: 11

[已解决]为什么先加读锁再加写锁不可以?

[复制链接]
发表于 2021-10-11 16:39:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

                               
登录/注册后可看大图
最佳答案
2021-10-12 23:23:55
好了,我的基础知识补充的差不多了,开始回答你的问题
为什么先加读锁再加写锁不可以?
这是规定了的,规定了不可以
读锁 锁的是其他进程的 写锁
写锁 锁的是其他进程的 读锁 和 写锁
原文是这么说的

  1.        When a shared lock is set on a segment of a file, other processes shall be able to set shared locks on that segment or a portion of  it.  A
  2.        shared  lock  prevents  any  other process from setting an exclusive lock on any portion of the protected area. A request for a shared lock
  3.        shall fail if the file descriptor was not opened with read access.

复制代码


下面是谷歌翻译的
  1. 当在文件的一个段上设置共享锁时,其他进程应该能够在该段或它的一部分上设置共享锁。 共享锁可防止任何其他进程在受保护区域的任何部分设置排他锁。 如果文件描述符不是用读访问打开的,则对共享锁的请求将失败。
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-12 18:08:36 | 显示全部楼层
这个问题很简单,因为我看不到你的代码,所以不知道为什么
你看,简单吧

为什么别人不理你,不回复你的这个问题?问题出在自己身上
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-12 18:18:16 | 显示全部楼层
发代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-12 18:28:21 | 显示全部楼层


                               
登录/注册后可看大图

                               
登录/注册后可看大图

                               
登录/注册后可看大图

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-12 18:32:01 | 显示全部楼层

这也是别人不理你的原因之一,你发图片,别人就要照着图片抄代码,你发文本,别人就可以直接复制代码,你觉得别人会选择照着图片抄代码吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-12 18:41:07 | 显示全部楼层
人造人 发表于 2021-10-12 18:32
这也是别人不理你的原因之一,你发图片,别人就要照着图片抄代码,你发文本,别人就可以直接复制代码,你 ...
  1. /* lock_set.c �ú������ã���fd�ļ�����������Ӧ���ļ���type���͵���(������������д�������) */

  2. int lock_set(int fd, int type)
  3. {
  4.         struct flock old_lock, lock;
  5.         lock.l_whence = SEEK_SET;/* �ļ���дָ����ʼλ�����ļ���ͷ */
  6.         lock.l_start = 0;        /*���λ���������������ļ�??*/
  7.         lock.l_len = 0;          /*�������򳤶ȣ����������ļ�*/
  8.         lock.l_type = type;      /*type������������д���ͽ����������ͣ���Ψһ��Ҫ��ֵ��������l_type��ֵ�ļ���*/
  9.         lock.l_pid = -1;         /*���ļ�ӵ���ļ����Ľ��̺ţ�Ĭ��Ϊ-1*/       
  10.        
  11.         fcntl(fd, F_GETLK, &lock);/* �ж��ļ��Ƿ�������� */
  12.                                   /*F_GETLK:����lock����ֵ�������Ƿ�������ֻ�д��ڽ���״̬����������*/
  13.                                   /*&lock:ȡflock�ṹ�����lock���׵�ַ*/
  14.         
  15.         /*�˴���fcntl()����ֻ��Ϊ�˲���fd�Ƿ�����������Ϊֻ���ļ�Ϊ����(������)״̬��������������ļ��Ѿ�������
  16.           ����F_GETLK������Ҫ������жϣ�
  17.           ���֮ǰ�Ѿ����ڵ��Ƕ����򻹿����϶����������д�������϶�����д����

  18.           Ҳ����˵��Ҫ��һ��û�������ļ�����Ҫִ������fcntl()������
  19.           ��һ��ִ�У�F_GETLK�������ļ�����Ϊ����״̬��fcntl()��������-1�����ĺ��徭�����Ը��ļ�����������
  20.           �ڶ���fcntl()����ִ�оͿ��Է��Ĵ󵨵�������fcntl()�����᷵��0�������ɹ�*/


  21.        
  22.         if (lock.l_type != F_UNLCK)/*���lock.l_type���ǽ���״̬����ζ���Ѿ�����������*/
  23.         {
  24.                 /* �ж��ļ�����������ԭ�� */
  25.                 if (lock.l_type == F_RDLCK) /* ���ļ����ж��� */
  26.                 {
  27.                         printf("Read lock already set by process PID:%d\n", lock.l_pid);
  28.                 }
  29.                 else if (lock.l_type == F_WRLCK) /* ���ļ�����д�� */
  30.                 {
  31.                         printf("Write lock already set by process PID:%d\n", lock.l_pid);
  32.                 }                       
  33.         }

  34.               
  35.        
  36.         lock.l_type = type;/* l_type �����ѱ�F_GETLK�޸Ĺ���������Ҫ���¸�ֵ*/
  37.        
  38. /* ���ݲ�ͬ��typeֵ��������ʽ�������������ν����ʽ����ζ�����û�гɹ������������׽���źţ������һֱ��������״̬ */
  39.         if ((fcntl(fd, F_SETLKW, &lock)) < 0)
  40.                       /*F_SETLKW&#65533;&#65533;&#65533;&#65533;&#65533;&#1975;&#65533;&#65533;&#65533;&#545;&#65533;&#65533;&#689;,&#65533;&#65533;&#65533;&#65533;&#751;&#65533;&#2019;&#65533;&#65533;&#65533;&#65533;&#65533;&#635;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1533;&#65533;&#65533;&#65533;&#378;&#355;&#65533;&#65533;&#753019;&#65533;*/
  41.                       /*&lock:&#545;flock&#65533;&#7801;&#65533;&#65533;&#65533;&#65533;&#65533;lock&#65533;&#65533;&#65533;&#1525;&#65533;&#1463;*/

  42.          /*&#65533;&#756;&#65533;fcntl()&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#227;&#65533;&#65533;&#65533;fd&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1254;&#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;lock&#65533;&#7801;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#567;&#65533;&#65533;&#65533;&#65533;l_type&#65533;&#65533;&#65533;&#885;&#65533;&#65533;&#65533;&#65533;&#65533;
  43.                                 &#65533;&#65533;&#689;&#65533;&#65533;F_GETLKW&#1457;&#65533;&#1272;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#938;&#65533;&#65533;&#1211;&#65533;&#65533;fcntl()&#65533;&#65533;&#65533;&#65533;&#65533;&#1150;&#65533;&#65533;&#65533;&#65533;&#1337;&#65533;
  44.                                 &#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#497;&#65533;&#65533;&#65533;fcntl()&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1331;&#633;&#65533;&#1460;&#65533;У&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;0 */

  45.         {
  46.                 printf("Lock failed:type = %d\n", lock.l_type);
  47.                 return 1;
  48.         }
  49.                
  50.         switch(lock.l_type)
  51.         {
  52.                 case F_RDLCK:
  53.                 {
  54.                         printf("Read lock set by process PID:%d\n", getpid());/*&#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#1137;&#65533;getpid()&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#758;&#65533;&#65533;&#65533;*/
  55.                 }
  56.                 break;

  57.                 case F_WRLCK:
  58.                 {
  59.                         printf("Write lock set by process PID:%d\n", getpid());/*&#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#1137;&#65533;getpid()&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;д&#65533;&#65533;*/
  60.                 }
  61.                 break;

  62.                 case F_UNLCK:
  63.                 {
  64.                         printf("Release lock by process PID:%d\n", getpid());/*&#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#1137;&#65533;getpid()&#65533;&#65533;&#65533;&#829;&#65533;&#65533;&#65533;*/
  65.                         return 1;
  66.                 }
  67.                 break;

  68.                 default:
  69.                 break;
  70.         }/* end of switch  */
  71.        
  72.         return 0;
  73. }

  74. /* read_lock.c */

  75. #include <unistd.h>
  76. #include <sys/file.h>
  77. #include <sys/types.h>
  78. #include <sys/stat.h>
  79. #include <stdio.h>
  80. #include <stdlib.h>
  81. #include "lock_set.c"

  82. int main(void)
  83. {
  84.         int fd;
  85.        
  86.         fd = open("hello",O_RDWR | O_CREAT, 0644);
  87.         if(fd < 0)
  88.         {
  89.                 printf("Open file error\n");
  90.                 exit(1);
  91.         }       
  92.        
  93.         lock_set(fd, F_RDLCK);/* &#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#1014;&#65533;&#545;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1717;&#564;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1463;&#65533;&#65533;&#309;&#564;&#65533;&#1524;&#812;&#65533;&#65533; */

  94.         getchar();/*&#545;&#65533;&#65533;&#65533;&#828;&#65533;&#65533;&#65533;&#65533;&#65533;&#1463;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;ó&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1460;&#65533;&#65533;&#65533;&#65533;&#549;*/       
  95.        
  96.         lock_set(fd, F_UNLCK);/* &#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#65533; */

  97.         getchar();
  98.        
  99.         close(fd);
  100.         exit(0);
  101. }
  102. /* write_lock.c */
  103. #include <unistd.h>
  104. #include <sys/file.h>
  105. #include <sys/types.h>
  106. #include <sys/stat.h>
  107. #include <stdio.h>
  108. #include <stdlib.h>
  109. #include "lock_set.c"

  110. int main(void)
  111. {
  112.         int fd;       
  113.        
  114.         fd = open("hello",O_RDWR | O_CREAT, 0644);/* &#65533;&#65533;&#65533;&#564;&#65533;&#65533;&#316;&#65533; */
  115.         if(fd < 0)
  116.         {
  117.                 printf("Open file error\n");
  118.                 exit(1);
  119.         }       
  120.        
  121.         lock_set(fd, F_WRLCK);/* &#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;д&#65533;&#65533;&#65533;&#65533; */
  122.         getchar();       
  123.        
  124.         lock_set(fd, F_UNLCK);/* &#65533;&#65533;&#65533;&#316;&#65533;&#65533;&#65533;&#65533;&#65533; */
  125.         getchar();
  126.        
  127.         close(fd);
  128.        
  129.         exit(0);
  130. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-12 18:56:45 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-12 18:57:16 | 显示全部楼层
改成 utf-8 格式看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-12 19:32:38 | 显示全部楼层
人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看

  1. /* lock_set.c 该函数作用:给fd文件描述符所对应的文件上type类型的锁(包括:读锁、写锁或解锁) */

  2. int lock_set(int fd, int type)
  3. {
  4.         struct flock old_lock, lock;
  5.         lock.l_whence = SEEK_SET;/* 文件读写指针起始位置在文件开头 */
  6.         lock.l_start = 0;        /*相对位移量;加锁整个文件??*/
  7.         lock.l_len = 0;          /*加锁区域长度;加锁整个文件*/
  8.         lock.l_type = type;      /*type包含:读锁、写锁和解锁三个类型;给唯一需要赋值的锁类型l_type赋值文件锁*/
  9.         lock.l_pid = -1;         /*该文件拥有文件锁的进程号,默认为-1*/       
  10.        
  11.         fcntl(fd, F_GETLK, &lock);/* 判断文件是否可以上锁 */
  12.                                   /*F_GETLK:根据lock参数值,决定是否上锁;只有处于解锁状态,才能上锁*/
  13.                                   /*&lock:取flock结构体变量lock的首地址*/
  14.         
  15.         /*此处的fcntl()函数只是为了测试fd是否能上锁,因为只有文件为解锁(不上锁)状态才能上锁;如果文件已经上锁,
  16.           根据F_GETLK参数就要看情况判断:
  17.           如果之前已经存在的是读锁则还可以上读锁,如果是写锁则不能上读锁或写锁;

  18.           也就是说:要给一个没上锁的文件上锁要执行两次fcntl()函数;
  19.           第一次执行:F_GETLK参数将文件设置为解锁状态;fcntl()函数返回-1,表达的含义经过测试该文件可以上锁;
  20.           第二次fcntl()函数执行就可以放心大胆的上锁,fcntl()函数会返回0,上锁成功*/


  21.        
  22.         if (lock.l_type != F_UNLCK)/*如果lock.l_type不是解锁状态,意味着已经存在其他锁*/
  23.         {
  24.                 /* 判断文件不能上锁的原因 */
  25.                 if (lock.l_type == F_RDLCK) /* 该文件已有读锁 */
  26.                 {
  27.                         printf("Read lock already set by process PID:%d\n", lock.l_pid);
  28.                 }
  29.                 else if (lock.l_type == F_WRLCK) /* 该文件已有写锁 */
  30.                 {
  31.                         printf("Write lock already set by process PID:%d\n", lock.l_pid);
  32.                 }                       
  33.         }

  34.               
  35.        
  36.         lock.l_type = type;/* l_type 可能已被F_GETLK修改过,所以需要重新赋值*/
  37.        
  38. /* 根据不同的type值进行阻塞式上锁或解锁,所谓阻塞式:意味着如果没有成功上锁或解锁或捕捉到信号,则程序一直处于阻塞状态 */
  39.         if ((fcntl(fd, F_SETLKW, &lock)) < 0)
  40.                       /*F_SETLKW:在无法获取锁时,进入睡眠;如果可获得锁或捕捉到信号,则返回*/
  41.                       /*&lock:取flock结构体变量lock的首地址*/

  42.          /*此处fcntl()函数作用:给fd文件描述符所对应的文件上lock结构体变量所确定的l_type类型的锁;
  43.                                 此时用F_GETLKW直接给文件上文件锁,因为第一次fcntl()函数已经测试过
  44.                                 该文件可以上锁,于是本次fcntl()函数可以成功执行,并返回0 */

  45.         {
  46.                 printf("Lock failed:type = %d\n", lock.l_type);
  47.                 return 1;
  48.         }
  49.                
  50.         switch(lock.l_type)
  51.         {
  52.                 case F_RDLCK:
  53.                 {
  54.                         printf("Read lock set by process PID:%d\n", getpid());/*该文件已被getpid()进程上了读锁*/
  55.                 }
  56.                 break;

  57.                 case F_WRLCK:
  58.                 {
  59.                         printf("Write lock set by process PID:%d\n", getpid());/*该文件已被getpid()进程上了写锁*/
  60.                 }
  61.                 break;

  62.                 case F_UNLCK:
  63.                 {
  64.                         printf("Release lock by process PID:%d\n", getpid());/*该文件已被getpid()进程解锁*/
  65.                         return 1;
  66.                 }
  67.                 break;

  68.                 default:
  69.                 break;
  70.         }/* end of switch  */
  71.        
  72.         return 0;
  73. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-12 19:33:10 | 显示全部楼层
人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看

  1. /* read_lock.c */

  2. #include <unistd.h>
  3. #include <sys/file.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "lock_set.c"

  9. int main(void)
  10. {
  11.         int fd;
  12.        
  13.         fd = open("hello",O_RDWR | O_CREAT, 0644);
  14.         if(fd < 0)
  15.         {
  16.                 printf("Open file error\n");
  17.                 exit(1);
  18.         }       
  19.        
  20.         lock_set(fd, F_RDLCK);/* 给文件上读取锁,上锁后程序处于等待键盘输入字符的等待状态; */

  21.         getchar();/*取键盘键入的字符,可以让程序继续执行下去*/       
  22.        
  23.         lock_set(fd, F_UNLCK);/* 给文件解锁 */

  24.         getchar();
  25.        
  26.         close(fd);
  27.         exit(0);
  28. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-12 19:33:40 | 显示全部楼层
人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看
  1. /* write_lock.c */
  2. #include <unistd.h>
  3. #include <sys/file.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "lock_set.c"

  9. int main(void)
  10. {
  11.         int fd;       
  12.        
  13.         fd = open("hello",O_RDWR | O_CREAT, 0644);/* 首先打开文件 */
  14.         if(fd < 0)
  15.         {
  16.                 printf("Open file error\n");
  17.                 exit(1);
  18.         }       
  19.        
  20.         lock_set(fd, F_WRLCK);/* 给文件上写入锁 */
  21.         getchar();       
  22.        
  23.         lock_set(fd, F_UNLCK);/* 给文件解锁 */
  24.         getchar();
  25.        
  26.         close(fd);
  27.        
  28.         exit(0);
  29. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-12 23:23:55 | 显示全部楼层    本楼为最佳答案   
好了,我的基础知识补充的差不多了,开始回答你的问题
为什么先加读锁再加写锁不可以?
这是规定了的,规定了不可以
读锁 锁的是其他进程的 写锁
写锁 锁的是其他进程的 读锁 和 写锁
原文是这么说的

  1.        When a shared lock is set on a segment of a file, other processes shall be able to set shared locks on that segment or a portion of  it.  A
  2.        shared  lock  prevents  any  other process from setting an exclusive lock on any portion of the protected area. A request for a shared lock
  3.        shall fail if the file descriptor was not opened with read access.

复制代码


下面是谷歌翻译的
  1. 当在文件的一个段上设置共享锁时,其他进程应该能够在该段或它的一部分上设置共享锁。 共享锁可防止任何其他进程在受保护区域的任何部分设置排他锁。 如果文件描述符不是用读访问打开的,则对共享锁的请求将失败。
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-21 12:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表