linux 文件读写 锁操作

linux 文件读写 锁操作  

2011-04-15 16:44:46|  分类: linux |  标签:ubuntu  linux    文件读写   |举报 |字号 订阅

linux文件操作学习(linux c 编程实战)。
锁的规则:
多进程:锁的不兼容性规则:
      多进程在给一个给定的字节上可以有一把共享的读锁,但是在一个给定的字节上的写锁则只能由一个进程单独使用。进一步而言,如果在一个给定字节上已经由一把或多把读锁,则不能在该字节傻瓜嗯再加写锁 ,如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。
单进程:
       一个进程设置某一文件区域傻瓜嗯的一种锁。如果某一文件区域已经存在文件记录锁,则如果此时再设置新的锁在该区域的话,旧的锁将会被新的锁取代。
注:多进程的锁的不兼容性规则不适用于单进程
实例:lock.c

linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹... 
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹... 
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹... 
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹... 
    linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 执行结果:
单进程锁得设置:
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 
 程序首先测试能不能在文件上加上读锁,测试结果表明可以在指定文件上设置读锁,于是在文件上设置了读锁。然后从文件中进行读操作,并将读出来的数据打印出来。再测试能不能在文件上加上写锁,测试结果表明可以在指定文件上设置写锁,于是又在文件上设置了写锁。
多进程锁演示:
打开两个终端,分别运行程序lock.c
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 等待然后运行另一终端
 
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 仍然可以读,然后切换到第一个进程,继续运行得
linux 文件读写 锁操作 - 树上鱼 - 水中鱼腹...
 进程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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值