文件锁

fcntl解决文件共享的问题,而select处理I/O复用的情况。

flock 用于对文件施加建议性锁而 fcntl 不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl 还能对文件的某一记录进行 上锁,也就是记录锁。 

记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,它能够使多个进程都能在 文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个进程在文件的 某个部分上建立写入锁。当然,在文件的同一部分不能同时建立读取锁和写入锁。

 #include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

函数原型 int fcnt1(int fd,int cmd,struct flock *lock)

struct flock{

short l_type;    //锁的类型F_RDLCK读取锁(共享锁),F_WRLCK写入锁(排斥锁),F_UNLCK解锁

off_t l_start;    //相对位移量(字节)

short l_whence;    //相对位移量的起点

off_t l_len;      //加锁区的长度

pid_t l_pid;

}

#include<stdio.h>
#include<sys/file.h>		//
#include<sys/stat.h>		//文件状态
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int lock_set(int fd,int type)
{
	struct flock lock;
	lock.l_start=0;
	lock.l_whence=SEEK_SET;
	lock.l_len=10;

	while(1){
		lock.l_type=type;
		/*根据不同的type给文件上锁或解锁*/
		if((fcntl(fd,F_SETLK,&lock))==0){		//F_SETLK设置lock描述的锁
			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;				//如果上锁成功,则函数返回
		}
		fcntl(fd,F_GETLK,&lock);		//F_GETLK获取文件的锁描述,赋给lock
		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 alrady set by %d\n",lock.l_pid);
			getchar();
		}
	}
}

int main()
{
	int fd;
	//打开文件
	fd=open("test",O_RDWR|O_CREAT,0666);
	if(fd<0){
		perror("open");
		exit(1);
	}

	//给文件上写入锁
	lock_set(fd,F_WRLCK);

	//用户按下一个键后解锁
	getchar();
	lock_set(fd,F_UNLCK);

	getchar();
	close(fd);
	exit(0);
}

在两个终端上同时运行这个程序试一下。

进程1对文件设置排斥锁后其他进程就不能再对文件设置排斥锁;但是多个进程可以对同一个文件设置共享锁。

posted @ 2011-01-21 19:09  高性能golang  阅读(836)  评论(0编辑  收藏  举报