linuxC多进程通讯---文件锁

•什么是文件锁

•英文名:file lock,在同一时刻只允许一个进程对文件进行访问
•建议性锁:advisory locking,又称协同锁
–内核只提供加减锁以及检测是否加锁,不提供锁的控制与协调工作
–需要多进程相互检测确认的加锁机制
–A进程对一个操作的文件加了锁
–B进程同样可以对该文件进行读写操作
–只有当B进程也对该文件加锁,文件锁才能起到同步作用
–Linux一般使用建议锁,而Windows一般使用强制性锁
•强制性锁: mandatory locking
–进程对文件进行I/O操作是,内核内部会检测该文件是否被加锁
–A进程对一个操作的文件加了锁
–当B进程对该文件进行I/O操作时,内核若检测该文件加了强制锁,B进程的操作则会失败

•系统调用:flock

•函数原型:int flock (int fd, int operation);
•函数功能:给整个文件添加或解除一个建议锁
•函数参数:operation
–LOCK_SH:共享锁
–LOCK_EX:独占锁、排他锁
–LOCK_UN:移除锁
•TIPS
–Flock只提供加锁、解锁机制,不提供锁检查
–需要用户自己检测,达到多进程同步操作
–用户若不自己检测,同样可以对一个已经加锁的文件进行读写操作

•系统调用:fcntl

•函数原型: int fcntl (int fd, int cmd, … /* arg */ );
•函数功能:给文件(部分文件)进行加锁、解锁操作
•函数参数:cmd
–F_SETLK:非阻塞式申请锁
–F_SETLKW:阻塞式申请锁
–F_GETLK:获取锁的相关信息
•记录锁
–读锁F_RDLCK,写锁F_WRLCK,释放锁F_UNLCK
在这里插入图片描述

•系统调用:lockf

•函数原型:int lockf (int fd, int cmd, off_t len);
•函数功能:
–可以更细粒度地对文件进行加锁、解锁操作
–库函数lockf是对系统调用fcntl的封装
•函数参数:operation
–F_LOCK:对文件某一区域添加独占锁
–F_TLOCK:非阻塞式申请锁
–F_ULOCK:对文件某一区域解锁

示例flock

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>

int main (void)
{
	int fd, i;
	char filename[] = "data.log";
	extern int errno;
	fd = open (filename, O_WRONLY | O_CREAT, 0666);
	if (fd != -1)
	{
		printf ("open file %s success \n", filename);
		printf ("pls input a num to lock the file.\n");
		scanf ("%d", &i);
        printf ("try to lock the file...\n");
		if (flock (fd, LOCK_EX) == 0)
			printf ("lock file success\n");
		else
			printf ("lock file failed\n");
        write (fd, "hello", 5);
		printf ("input a num to Unlock the file.\n");
		scanf ("%d", &i);
		if (flock (fd, LOCK_UN) == 0)
			printf ("file unlock success\n");
		else
			printf ("file unlock failed\n");

        while (1);
	}
	else
	{
		perror ("open");
		exit (EXIT_FAILURE);
	}
	return 0;
}

示例fcntl

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>


int main (int argc, char *argv[])
{
	if (argc > 1)
	{
		int fd = open (argv[1], O_WRONLY | O_CREAT, 0666);
		if (fd == -1)
		{
			perror ("open");
			exit (-1);
		}
		static struct flock lock;
		lock.l_type = F_WRLCK;
		lock.l_start = 0;
		lock.l_whence = SEEK_SET;
		lock.l_len = 0;
		lock.l_pid = getpid();

        printf ("trying lock %s ...\n", argv[1]);
		int ret = fcntl (fd, F_SETLKW, &lock);
		if (ret == 0)
		{
		    printf ("lock %s succeed\n", argv[1]);
            while (1);
		}
	}
	return 0;
}

示例lockf

flock 和lockf 可以共同加锁,互不影响

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
int main (int argc, char *argv[])
{
	int fd, ret;
	int pid;
	fd = open ("tmp.txt", O_RDWR | O_CREAT, 0666);
	ret = flock (fd, LOCK_EX);
	printf ("flock return ret:%d\n", ret);
	ret = lockf (fd, F_LOCK, 0);
	printf ("lockf return ret:%d\n", ret);
	sleep (30);
	return 0;
}
发布了349 篇原创文章 · 获赞 6 · 访问量 9741

猜你喜欢

转载自blog.csdn.net/qq_23929673/article/details/100173811