为什么先加读锁再加写锁不可以?
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: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:28
这也是别人不理你的原因之一,你发图片,别人就要照着图片抄代码,你发文本,别人就可以直接复制代码,你觉得别人会选择照着图片抄代码吗?
人造人 发表于 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��������ȡ��ʱ,����˯�ߣ�����ɻ���������źţ��򷵻�*/
/*&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:41
乱码了 改成 utf-8 格式看看 人造人 发表于 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 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 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);
} 好了,我的基础知识补充的差不多了,开始回答你的问题
为什么先加读锁再加写锁不可以?
这是规定了的,规定了不可以
读锁 锁的是其他进程的 写锁
写锁 锁的是其他进程的 读锁 和 写锁
原文是这么说的
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]