系统调用文件IO存在线程安全的问题,当多个用户共同使用、操作一个文件的时候,Linux 通常采用的方法是给文件上锁,来避免共享资源产生竞争的状态。
文件锁可以分为共享读锁和独占写锁。共享读锁:文件必须使用只读打开,一个进程上了读锁,其他进程还可以上读锁,此时,无法进行写操作。独占写锁:文件必须受用只写打开,一个进程上了写锁,其他进程就不能上读写锁了,这就是读写互斥。
这里我们依旧用上一节的fcntl函数。
int fcntl(int fd, int cmd, struct flock *lock);
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
__kernel_off_t l_start;
__kernel_off_t l_len;
__kernel_pid_t l_pid;
__ARCH_FLOCK_PAD
};
下面给出一段代码,可以测试互斥写和共享读锁,测试的时候需要开两个中端,这样才能看出来效果。代码是从这位博主那抄来的(https://www.cnblogs.com/mingfeng002/p/6962915.html),今天心情有些不好,以后有时间单独写一个个测试代码贴过来
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
void lock_set(int fd, int type)
{
struct flock lock;
lock.l_whence = SEEK_SET;//赋值lock结构体
lock.l_start = 0;
lock.l_len = 0;
while (1){
lock.l_type = type;
/*根据不同的type值给文件上锁或解锁*/
if ((fcntl(fd, F_SETLK, &lock)) == 0){
if (lock.l_type == F_RDLCK)
printf("read lock set by %d\n", getpid());
else if (lock.l_type == F_WRLCK)
printf("write lock set by %d\n", getpid());
else if (lock.l_type == F_UNLCK)
printf("release lock by %d\n", getpid());
return;
}
/*判断文件是否可以上锁*/
int re = fcntl(fd, F_GETLK, &lock);
printf("%d\n",re);
/*判断文件不能上锁的原因*/
if (lock.l_type != F_UNLCK){
/*/该文件已有写入锁*/
if (lock.l_type == F_RDLCK)
printf("read lock already set by %d\n", lock.l_pid);
/*该文件已有读取锁*/
else if (lock.l_type == F_WRLCK)
printf("write lock already set by %d\n", lock.l_pid);
getchar();
}
}
}
int main(void)
{
struct flock lock;
pid_t pid;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = F_RDLCK;
int fd;
fd = open("demo5.txt", O_RDWR | O_CREAT, 0666);
if (fd < 0){
perror("open");
exit(1);
}
lock_set(fd, F_WRLCK);//互斥写F_WRLCK 共享读F_RDLCK 修改这里就可以测试互斥写和共享读
getchar();
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}