Linux系统编程62 高级IO - 文件锁,lockf()

文件锁的方法:

fcntl()
lockf()
flock()


NAME
       lockf - apply, test or remove a POSIX lock on an open file

SYNOPSIS
       #include <unistd.h>

/*
fd:需要锁的目标文件
len: 要锁多长,0表示 文件有多长 锁多长,即加锁到文件末端,就算文件加长 也会随之锁上
cmd :实现的命令
F_LOCK  解锁,阻塞式加锁
F_TLOCK 尝试加锁,非阻塞式加锁
F_ULOCK 解锁
       F_TEST  测试有没有锁
*/
       int lockf(int fd, int cmd, off_t len);

注意:
给一个文件加锁,参数指定fd,通过文件描述符给文件加锁,加锁是加到了文件本身,即inode层面,并不是每个fd所对应的文件属性结构体。注意:当一个进程打开两次同一个文件的时候,如图中所用的第一个和第三个,指向不同的文件属性结构体,但是都是指向同一个 inode文件,这种情况 如果一个加锁后,另一个执行close()文件,会造成加锁的文件被意外解锁。
在这里插入图片描述

实验:多进程并发,实现20个进程操作同一个文件,每个进程打开+1 。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>

#define PROCNUM 20
#define FNAME "/home/mhr/Desktop/xitongbiancheng/super_io/out"
#define LINESIZE 1024


static void func_add(void)
{
	FILE *fp;
	int fd;
	char linebuf[LINESIZE];

	fp = fopen(FNAME,"r+");
	if(fp == NULL)
	{
		perror("fopen()");
		exit(1);
	}

fd = fileno(fp);//返回文件描述符
//if(fd < 0)

//上锁,加锁到文件末端
lockf(fd,F_LOCK,0);

	fgets(linebuf,LINESIZE,fp);
	fseek(fp,0,SEEK_SET);

	//sleep(1);	
	
//文件的全缓冲,而fprintf是航缓冲,所以解锁前没有close() 写操作就不能将数据写到文件中,需要ffllush()刷新流
	fprintf(fp,"%d\n",atoi(linebuf)+1);
	fflush(fp);//刷新
//解锁
lockf(fd,F_ULOCK,0);
	
//解锁后 close()  防止意外解锁
	fclose(fp);
return;

} 

int main()
{
	int i,err;
	pid_t pid;

	for(i = 0; i < PROCNUM; i++)
	{
		pid = fork();//创建20个子进程
		if(pid < 0)
		{
			perror("fork()");
			exit(1);
		}
		
		if(pid == 0)//Child 
		{
			func_add();
			exit(0);//子进程操作后就结束
		}

	}

	for(i = 0;i < PROCNUM; i++)
	{
		wait(NULL);//父进程收尸
	}

	exit(0);
	
}

猜你喜欢

转载自blog.csdn.net/LinuxArmbiggod/article/details/114694863