四、文件锁的使用
1、在进程PA操作文件的时候先加锁,加锁成功后然后访问文件。在加锁期间其他进程不能对文件进行改动
2、访问结束后释放锁
文件锁分为两种:读锁(共享锁)和写锁(互斥锁)
文件对锁的实现分为两类:建议锁和强制锁
3、如何对文件加锁:
使用系统调用fcntl(2)对文件的加锁
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
功能:操作文件描述符
参数:
fd:指定了要操控的文件描述
cmd:指定了操作文件描述符(这里的三个都需要第三个参数)
F_GETLK:用来测试是否可以加锁,如果可以,返回F_UNLCK。不可以加锁在字段l_pid中保存了一个pid。是hold着这把锁的进程的pid
F_SETLK:为文件描述符设置锁,如果有互斥锁,其他进程hold着互斥锁,立即返回-1,错误,errno被设置
F_SETLKW:和F_SETLK一样,但是如果想要加的锁和文件已有记录锁冲突,进程阻塞等待进程对记录锁的释放
...:可变参数,参数的类型和个数取决于CMD
struct flock *
struct flock {
...
short l_type; /* Type of lock: F_RDLCK,F_WRLCK, F_UNLCK */ 读取锁(共享锁),写入锁(排斥锁),解锁
相对位移量的起点short l_whence; /* How to interpret l_start:EEK_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) */
...
};
返回值:0代表成功
-1 错误 errno被设置
举例:文件锁的使用
有两个进程PA,PB,PA进程对文件加读锁,PB进程对同一文件也加读锁,是否成功?(PA.c,PB.c)
#include <stdio.h>
#include <p_file.h>
int main(int argc, char *argv[]) {
int fd = open(argv[1], O_RDONLY);
struct flock lock;
if(fd == -1) {
perror("open");
return -1;
}
//对锁变量设置初值
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_pid = 0;
//对文件描述符加锁
int f = fcntl(fd, F_SETLK, &lock);
if(f == -1) {
perror("fcntl");
return -1;
}
getchar();
//close 将关闭掉文件描述符上的所有记录锁
close(fd);
return 0;
}
A为写锁,B为写锁
A:
tarena@ubuntu:~/day/day28$ A hello
-
B
tarena@ubuntu:~/day/day28$ gcc PB.c -o B
tarena@ubuntu:~/day/day28$ B hello
add lock success..
A为写锁,B为读锁
修改:int fd = open(argv[1], O_WRONLY);
lock.l_type = F_WRLCK
A:
tarena@ubuntu:~/day/day28$ A hello
-
B:
tarena@ubuntu:~/day/day28$ B hello
-
当进程A结束,B马上加锁成功
举例:测试文件锁是否能添加。(PC.c PD.c)(程序PA运行中进行下面)
PC.c:
#include <stdio.h>
#include <p_file.h>
int main(int argc, char *argv[]) {
struct flock lock;
int fd = open(argv[1], O_RDONLY);
if(fd == -1) {
perror("open");
return -1;
}
//对锁变量设置初值
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_pid = 0;
int f = fcntl(fd, F_GETLK, &lock);
if(f == -1) {
perror("fcntl");
return -1;
}
if(lock.l_type == F_UNLCK) {
printf("can add read lock...\n");
}
else {
printf("hold lock %d of process",lock.l_pid);
}
return 0;
}
tarena@ubuntu:~/day/day28$ C hello
can add read lock...
分析: 读锁可以添加
PD.c
修改:
int fd = open(argv[1], O_WRONLY);
lock.l_type = F_WRLCK
tarena@ubuntu:~/day/day28$ D hello
hold lock 4350 of process
分析:写锁不能添加,返回占用的进程的PID
【C语言】【unix c】文件锁的使用
最新推荐文章于 2023-06-11 16:09:35 发布