微光拼图 发表于 2021-10-11 16:39:13

为什么先加读锁再加写锁不可以?

https://img-blog.csdnimg.cn/a3edd5321aa14cc5a222f2cb9a8b1e74.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDM2ODc2NTI=,size_20,color_FFFFFF,t_70,g_se,x_16

人造人 发表于 2021-10-12 18:08:36

这个问题很简单,因为我看不到你的代码,所以不知道为什么
你看,简单吧

为什么别人不理你,不回复你的这个问题?问题出在自己身上

人造人 发表于 2021-10-12 18:18:16

发代码

微光拼图 发表于 2021-10-12 18:28:21

人造人 发表于 2021-10-12 18:18
发代码

https://img-blog.csdnimg.cn/30e442e5f07445c3b675c8410957a64d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDM2ODc2NTI=,size_20,color_FFFFFF,t_70,g_se,x_16https://img-blog.csdnimg.cn/f55b06f12ddf47a7ab957b441d80f8ae.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDM2ODc2NTI=,size_20,color_FFFFFF,t_70,g_se,x_16https://img-blog.csdnimg.cn/c4b1c1dfb1de42ad9bb92c9120e55962.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDM2ODc2NTI=,size_20,color_FFFFFF,t_70,g_se,x_16https://img-blog.csdnimg.cn/a5641fb1298d408f801488451fd3c178.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDM2ODc2NTI=,size_20,color_FFFFFF,t_70,g_se,x_16

人造人 发表于 2021-10-12 18:32:01

微光拼图 发表于 2021-10-12 18:28


这也是别人不理你的原因之一,你发图片,别人就要照着图片抄代码,你发文本,别人就可以直接复制代码,你觉得别人会选择照着图片抄代码吗?

微光拼图 发表于 2021-10-12 18:41:07

人造人 发表于 2021-10-12 18:32
这也是别人不理你的原因之一,你发图片,别人就要照着图片抄代码,你发文本,别人就可以直接复制代码,你 ...

/* lock_set.c �ú������ã���fd�ļ�����������Ӧ���ļ���type���͵���(������������д�������) */

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

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


       
        if (lock.l_type != F_UNLCK)/*���lock.l_type���ǽ���״̬����ζ���Ѿ�����������*/
        {
                /* �ж��ļ�����������ԭ�� */
                if (lock.l_type == F_RDLCK) /* ���ļ����ж��� */
                {
                        printf("Read lock already set by process PID:%d\n", lock.l_pid);
                }
                else if (lock.l_type == F_WRLCK) /* ���ļ�����д�� */
                {
                        printf("Write lock already set by process PID:%d\n", lock.l_pid);
                }                       
        }

              
       
        lock.l_type = type;/* l_type �����ѱ�F_GETLK�޸Ĺ���������Ҫ���¸�ֵ*/
       
/* ���ݲ�ͬ��typeֵ��������ʽ�������������ν����ʽ����ζ�����û�гɹ������������׽���źţ������һֱ��������״̬ */
        if ((fcntl(fd, F_SETLKW, &lock)) < 0)
                      /*F_SETLKW�����޷���ȡ��ʱ,����˯�ߣ�����ɻ������׽���źţ��&#753019;�*/
                      /*&lock:ȡflock�ṹ�����lock���׵�ַ*/

         /*�˴�fcntl()�������ã���fd�ļ�����������Ӧ���ļ���lock�ṹ�������ȷ����l_type���͵�����
                              ��ʱ��F_GETLKWֱ�Ӹ��ļ����ļ�������Ϊ��һ��fcntl()�����Ѿ����Թ�
                              ���ļ��������������DZ���fcntl()�������Գɹ�ִ�У�������0 */

        {
                printf("Lock failed:type = %d\n", lock.l_type);
                return 1;
        }
               
        switch(lock.l_type)
        {
                case F_RDLCK:
                {
                        printf("Read lock set by process PID:%d\n", getpid());/*���ļ��ѱ�getpid()�������˶���*/
                }
                break;

                case F_WRLCK:
                {
                        printf("Write lock set by process PID:%d\n", getpid());/*���ļ��ѱ�getpid()��������д��*/
                }
                break;

                case F_UNLCK:
                {
                        printf("Release lock by process PID:%d\n", getpid());/*���ļ��ѱ�getpid()���̽���*/
                        return 1;
                }
                break;

                default:
                break;
        }/* end of switch*/
       
        return 0;
}

/* read_lock.c */

#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"

int main(void)
{
        int fd;
       
        fd = open("hello",O_RDWR | O_CREAT, 0644);
        if(fd < 0)
        {
                printf("Open file error\n");
                exit(1);
        }       
       
        lock_set(fd, F_RDLCK);/* ���ļ��϶�ȡ��������������ڵȴ����������ַ��ĵȴ�״̬�� */

        getchar();/*ȡ���̼�����ַ��������ó������ִ����ȥ*/       
       
        lock_set(fd, F_UNLCK);/* ���ļ����� */

        getchar();
       
        close(fd);
        exit(0);
}
/* write_lock.c */
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"

int main(void)
{
        int fd;       
       
        fd = open("hello",O_RDWR | O_CREAT, 0644);/* ���ȴ��ļ� */
        if(fd < 0)
        {
                printf("Open file error\n");
                exit(1);
        }       
       
        lock_set(fd, F_WRLCK);/* ���ļ���д���� */
        getchar();       
       
        lock_set(fd, F_UNLCK);/* ���ļ����� */
        getchar();
       
        close(fd);
       
        exit(0);
}

人造人 发表于 2021-10-12 18:56:45

微光拼图 发表于 2021-10-12 18:41


乱码了

人造人 发表于 2021-10-12 18:57:16

改成 utf-8 格式看看

微光拼图 发表于 2021-10-12 19:32:38

人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看


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

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

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


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

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

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

        {
                printf("Lock failed:type = %d\n", lock.l_type);
                return 1;
        }
               
        switch(lock.l_type)
        {
                case F_RDLCK:
                {
                        printf("Read lock set by process PID:%d\n", getpid());/*该文件已被getpid()进程上了读锁*/
                }
                break;

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

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

                default:
                break;
        }/* end of switch*/
       
        return 0;
}

微光拼图 发表于 2021-10-12 19:33:10

人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看


/* read_lock.c */

#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"

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

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

        getchar();
       
        close(fd);
        exit(0);
}

微光拼图 发表于 2021-10-12 19:33:40

人造人 发表于 2021-10-12 18:57
改成 utf-8 格式看看

/* write_lock.c */
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"

int main(void)
{
        int fd;       
       
        fd = open("hello",O_RDWR | O_CREAT, 0644);/* 首先打开文件 */
        if(fd < 0)
        {
                printf("Open file error\n");
                exit(1);
        }       
       
        lock_set(fd, F_WRLCK);/* 给文件上写入锁 */
        getchar();       
       
        lock_set(fd, F_UNLCK);/* 给文件解锁 */
        getchar();
       
        close(fd);
       
        exit(0);
}

人造人 发表于 2021-10-12 23:23:55

好了,我的基础知识补充的差不多了,开始回答你的问题
为什么先加读锁再加写锁不可以?
这是规定了的,规定了不可以
读锁 锁的是其他进程的 写锁
写锁 锁的是其他进程的 读锁 和 写锁
原文是这么说的

       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 ofit.A
       sharedlockpreventsanyother process from setting an exclusive lock on any portion of the protected area. A request for a shared lock
       shall fail if the file descriptor was not opened with read access.



下面是谷歌翻译的
当在文件的一个段上设置共享锁时,其他进程应该能够在该段或它的一部分上设置共享锁。 共享锁可防止任何其他进程在受保护区域的任何部分设置排他锁。 如果文件描述符不是用读访问打开的,则对共享锁的请求将失败。
页: [1]
查看完整版本: 为什么先加读锁再加写锁不可以?