linux文件操作学习(linux c 编程实战)。
锁的规则:
多进程:锁的不兼容性规则:
多进程在给一个给定的字节上可以有一把共享的读锁,但是在一个给定的字节上的写锁则只能由一个进程单独使用。进一步而言,如果在一个给定字节上已经由一把或多把读锁,则不能在该字节傻瓜嗯再加写锁 ,如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。
单进程:
一个进程设置某一文件区域傻瓜嗯的一种锁。如果某一文件区域已经存在文件记录锁,则如果此时再设置新的锁在该区域的话,旧的锁将会被新的锁取代。
注:多进程的锁的不兼容性规则不适用于单进程
实例:lock.c
执行结果:
单进程锁得设置:
程序首先测试能不能在文件上加上读锁,测试结果表明可以在指定文件上设置读锁,于是在文件上设置了读锁。然后从文件中进行读操作,并将读出来的数据打印出来。再测试能不能在文件上加上写锁,测试结果表明可以在指定文件上设置写锁,于是又在文件上设置了写锁。
多进程锁演示:
打开两个终端,分别运行程序lock.c
等待然后运行另一终端
仍然可以读,然后切换到第一个进程,继续运行得
进程1设置了读锁,进程2仍然可以从文件中读数据,linux文件默认的锁是建议性锁!
复制代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
//自定义错误处理函数
void my_err(const char *err_string,int line)
{
fprintf(stderr,"line:%d ",line);
perror(err_string);
exit(1);
}
//锁的设置和释放函数
int lock_set(int fd,struct flock *lock)
{
if(fcntl(fd,F_SETLK,lock)==0)
{
if (lock->l_type==F_RDLCK)
printf("set read lock,pid:%d\n",getpid());
if(lock->l_type==F_WRLCK)
printf("set write lock ,pid:%d\n",getpid());
if (lock->l_type=F_UNLCK)
printf("release lock,pid:%d\n",getpid());
}
else
{
perror("lock operation fail\n");
return -1;
}
return 0;
}
//测试锁,只有当测试发现参数lock置顶的锁能被设置时,返回0
int lock_test(int fd,struct flock *lock)
{
if (fcntl(fd,F_GETLK,lock)==0)
{
if(lock->l_type==F_UNLCK)
{
printf("lock can be set in fd\n");
return 0;
}
else
{
if(lock->l_type==F_RDLCK)
printf("can't set lock,read lock has been set by:%d\n",lock->l_pid);
else if (lock->l_type==F_WRLCK)
printf("can't set lock,write lock has been set by:%d\n",lock->l_pid);
return -2;
}
}
else
{
perror("get incompatible locks fail");
return -1;
}
}
int main()
{
int fd;
int ret;
struct flock lock;
char read_buf[32];
char write_buf[32]="lock test";
//打开或创建文件
if((fd=open("rest.c",O_RDWR|O_CREAT|O_TRUNC, 0777))==-1)
my_err("open",__LINE__);
else
printf("create success\n");
if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
my_err("write",__LINE__);
else
printf("write success\n");
//初始化lock机构
memset(&lock,0,sizeof(struct flock));
lock.l_start=SEEK_SET;
lock.l_whence=0;
lock.l_len=0;
//设置读锁
lock.l_type=F_RDLCK;
if(lock_test(fd,&lock)==0)
{
lock.l_type=F_RDLCK;
lock_set(fd,&lock);
}
//读数据
lseek(fd,0,SEEK_SET);
if((ret=read(fd,read_buf,10))<0)
my_err("read",__LINE__);
read_buf[ret]='\0';
printf("%s\n",read_buf);
//等待任意按键
getchar();
//设置写锁
lock.l_type=F_WRLCK;
if(lock_test(fd,&lock)==0)
{
lock.l_type=F_WRLCK;
lock_set(fd,&lock);
}
//释放锁
lock.l_type=F_UNLCK;
lock_set(fd,&lock);
close(fd);
return 0;
}
锁的规则:
多进程:锁的不兼容性规则:
多进程在给一个给定的字节上可以有一把共享的读锁,但是在一个给定的字节上的写锁则只能由一个进程单独使用。进一步而言,如果在一个给定字节上已经由一把或多把读锁,则不能在该字节傻瓜嗯再加写锁 ,如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。
单进程:
一个进程设置某一文件区域傻瓜嗯的一种锁。如果某一文件区域已经存在文件记录锁,则如果此时再设置新的锁在该区域的话,旧的锁将会被新的锁取代。
注:多进程的锁的不兼容性规则不适用于单进程
实例:lock.c
单进程锁得设置:
多进程锁演示:
打开两个终端,分别运行程序lock.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
//自定义错误处理函数
void my_err(const char *err_string,int line)
{
fprintf(stderr,"line:%d ",line);
perror(err_string);
exit(1);
}
//锁的设置和释放函数
int lock_set(int fd,struct flock *lock)
{
if(fcntl(fd,F_SETLK,lock)==0)
{
if (lock->l_type==F_RDLCK)
printf("set read lock,pid:%d\n",getpid());
if(lock->l_type==F_WRLCK)
printf("set write lock ,pid:%d\n",getpid());
if (lock->l_type=F_UNLCK)
printf("release lock,pid:%d\n",getpid());
}
else
{
perror("lock operation fail\n");
return -1;
}
return 0;
}
//测试锁,只有当测试发现参数lock置顶的锁能被设置时,返回0
int lock_test(int fd,struct flock *lock)
{
if (fcntl(fd,F_GETLK,lock)==0)
{
if(lock->l_type==F_UNLCK)
{
printf("lock can be set in fd\n");
return 0;
}
else
{
if(lock->l_type==F_RDLCK)
printf("can't set lock,read lock has been set by:%d\n",lock->l_pid);
else if (lock->l_type==F_WRLCK)
printf("can't set lock,write lock has been set by:%d\n",lock->l_pid);
return -2;
}
}
else
{
perror("get incompatible locks fail");
return -1;
}
}
int main()
{
int fd;
int ret;
struct flock lock;
char read_buf[32];
char write_buf[32]="lock test";
//打开或创建文件
if((fd=open("rest.c",O_RDWR|O_CREAT|O_TRUNC, 0777))==-1)
my_err("open",__LINE__);
else
printf("create success\n");
if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
my_err("write",__LINE__);
else
printf("write success\n");
//初始化lock机构
memset(&lock,0,sizeof(struct flock));
lock.l_start=SEEK_SET;
lock.l_whence=0;
lock.l_len=0;
//设置读锁
lock.l_type=F_RDLCK;
if(lock_test(fd,&lock)==0)
{
lock.l_type=F_RDLCK;
lock_set(fd,&lock);
}
//读数据
lseek(fd,0,SEEK_SET);
if((ret=read(fd,read_buf,10))<0)
my_err("read",__LINE__);
read_buf[ret]='\0';
printf("%s\n",read_buf);
//等待任意按键
getchar();
//设置写锁
lock.l_type=F_WRLCK;
if(lock_test(fd,&lock)==0)
{
lock.l_type=F_WRLCK;
lock_set(fd,&lock);
}
//释放锁
lock.l_type=F_UNLCK;
lock_set(fd,&lock);
close(fd);
return 0;
}