China Open source community
站内导航:
站内排行前50热点文章

精华文章  GDB调试精粹及使用实例
普通文章  STL中map用法详解
精华文章  负载均衡软件比较(Hapr...
普通文章  头文件的重复引用
普通文章  递归函数的调用过程
普通文章  TCP三次握手/四次挥手详解
普通文章  贪心策略的理论基础——...
普通文章  BMH算法原理与实现(模...
普通文章  排列组合与回溯算法
普通文章  DP动态规划
精华文章  Android线程模型
普通文章  Linux socket编程之套接字
普通文章  Linux内核中的红黑树
精华文章  linux下使用minicom的几...
普通文章  Java开源Html解析类库
精华文章  enum类型的本质
普通文章  memcached server LRU ...
普通文章  linux设置环境变量的方法
普通文章  android核心模块及相关...
普通文章  linux源代码包(.tar.g...
普通文章  L.A.M.P配置过程
普通文章  在ubuntu9.10下安装QT4...
普通文章  C/C++程序员常见面试题...
普通文章  gcc编译过程概述
普通文章  python的memcache和jso...
普通文章  应用程序二进制接口---ABI
普通文章  linux内核编译问题
普通文章  Java多线程实现简单实例
普通文章  Python程序员常用的IDE...
普通文章  brk和sbrk详述
普通文章  优化C语言代码(程序员必...
普通文章  python非贪婪,多行匹配...
普通文章  函数指针传递和全局指针...
普通文章  Unix操作系统的历史演变
普通文章  网络编程之C10K问题
普通文章  发行版发布:CentOS 5.4
普通文章  在windows中构建gtk开发...
普通文章  i++循环与i--循环的执行...
普通文章  关于Qvariant类--万能的...
普通文章  Debian sudo 设置
普通文章  busybox1.15.x 交叉编译
普通文章  关于僵死进程zombie
普通文章  递归思想的妙用
普通文章  判断链表是否存在环并找...
普通文章  Android Porting Exper...
普通文章  关于/etc/bashrc和$HOM...
普通文章  [翻译]Django初窥
普通文章  Python list的排序
普通文章  Django实现大数据量分页...
普通文章  Debug方式取代printf满...

 
 
 
当前位置: 首页 >> 程序设计 >> fcntl在文件记录锁的应用编程
 
 

fcntl在文件记录锁的应用编程

作者:piaoxiang      来源:piaoxiang.cublog.cn     发表时间:2006-11-30     浏览次数:      字号:    

中国源码网内相关主题链接
  • fcntl在文件记录锁的应用编程
  • 锁设置子函数:

    /*
     * 设置记录锁子函数lock_set.c
     *
     * 记录锁分为读取锁和写入锁,其中读取锁又称为共享锁,可以使多个
     * 进程都能够在文件的同一部分建立读取锁。而写入锁又称为互斥锁,
     * 在任何时刻只能有一个进程在文件的某个部分建立写入锁。当然,在
     * 文件的同一部分不能同时建立读取锁和写入锁。
     *
     * fcntl的lock结构如下所示:
     * struct flock {
     * short l_type;
     * off_t l_start;
     * short l_whence;
     * off_t l_len;
     * pid_t l_pid;
     * }
     *
     * 技巧:为加锁整个文件,通常的方法是将l_start说明为0,l_whence
     * 说明为SEEK_SET,l_len说明为0。
     */


    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>

    void print_lock(struct flock lock)
    {
            printf(" -----------------------------\n");

            if (lock.l_type == F_RDLCK) {
                    printf("\tl_type: F_RDLCK\n");
            }
            else if (lock.l_type == F_WRLCK) {
                    printf("\tl_type: F_WRLCK\n");
            }
            else if (lock.l_type == F_UNLCK) {
                    printf("\tl_type: F_UNLCK\n");
            }

            printf("\tl_start: %d\n", (int)lock.l_start);

            if (lock.l_whence == SEEK_SET) {
                    printf("\tl_whence: SEEK_SET\n");
            }
            else if (lock.l_whence == SEEK_CUR) {
                    printf("\tl_whence: SEEK_CUR\n");
            }
            else if (lock.l_whence == SEEK_END) {
                    printf("\tl_whence: SEEK_END\n");
            }

            printf("\tl_len: %d\n", (int)lock.l_len);

            printf(" -----------------------------\n");
    }

    void lock_set(int fd, int type)
    {
            struct flock lock;

            /*赋值lock结构体,加锁整个文件*/
            lock.l_whence = SEEK_SET;
            lock.l_start = 0;
            lock.l_len = 0;

            while (1) {
                    lock.l_type = type;

                    /*
                     * 根据不同的type来给文件加锁或解锁,
                     * 如果成功,则返回0,失败则返回1。
                     * 举例:如果一个文件原来已经建立了互斥锁,那么再调用fcntl
                     * 建立锁就会失败,返回-1。
                     */

                    if ((fcntl(fd, F_SETLK, &lock)) == 0) {
                            /*如果是共享锁*/
                            if (lock.l_type == F_RDLCK) {
                                    printf("read only 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());
                            }
                            print_lock(lock);
                            return;
                    }
                    else {
                            /*
                             * 获得lock的描述,也就是将文件fd的加锁信息存入到lock结构中
                             * 如果成功则返回0
                             * 如果失败则返回-1
                             */

                            if ((fcntl(fd, F_GETLK, &lock)) == 0) {
                                    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 already set by %d\n", lock.l_pid);
                                            }
                                            getchar();
                                    }
                            }
                            else {
                                    printf("cannot get the description of struck flock.\n");
                            }
                    }
            }
    }

    读取锁:

    /*
     * 测试文件读取锁
     */


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

    void lock_set(int, int);

    void die(char *msg)
    {
            perror(msg);
            exit(1);
    }

    int open_file(void)
    {
            int fd;

            if ((fd = open("/tmp/hello.c", O_CREAT | O_TRUNC | O_RDWR, 0666)) < 0) {
                    die("open error");
            }
            else {
                    printf("Open file: hello.c %d\n", fd);
            }

            return fd;
    }

    void close_file(int fd)
    {
            if (close(fd) < 0) {
                    die("close error");
            }
            else {
                    printf("Close file: hello.c\n");
            }
    }

    int main(void)
    {
            int fd;

            fd = open_file();

            /*给文件加写入锁*/
            lock_set(fd, F_RDLCK);
            /*等待键盘任意键触发*/
            getchar();
            /*给文件解锁*/
            lock_set(fd, F_UNLCK);
            getchar();
            close_file(fd);

            return 0;
    }

    写入锁:

    /*
     * 测试文件写入锁
     */


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

    void lock_set(int, int);

    void die(char *msg)
    {
            perror(msg);
            exit(1);
    }

    int open_file(void)
    {
            int fd;

            if ((fd = open("/tmp/hello.c", O_CREAT | O_TRUNC | O_RDWR, 0666)) < 0) {
                    die("open error");
            }
            else {
                    printf("Open file: hello.c %d\n", fd);
            }

            return fd;
    }

    void close_file(int fd)
    {
            if (close(fd) < 0) {
                    die("close error");
            }
            else {
                    printf("Close file: hello.c\n");
            }
    }

    int main(void)
    {
            int fd;

            fd = open_file();

            /*给文件加写入锁*/
            lock_set(fd, F_WRLCK);
            /*等待键盘任意键触发*/
            getchar();
            /*给文件解锁*/
            lock_set(fd, F_UNLCK);
            getchar();
            close_file(fd);

            return 0;
    }

    Makefile源文件:

    CC = gcc
    OBJS = fcntl_write fcntl_read
    CFLAGS = -Wall -g

    all: $(OBJS)

    fcntl_write: fcntl_write.c lock_set.c
            $(CC) $(CFLAGS) $^ -o $@
    fcntl_read: fcntl_read.c lock_set.c
            $(CC) $(CFLAGS) $^ -o $@

    .PHONY: clean
    clean:
            rm -rf $(OBJS)

    测试结果:

    [armlinux@lqm fcntl]$ ./fcntl_read
    Open file: hello.c 3
    read only set by 12398
       -----------------------------
            l_type: F_RDLCK
            l_start: 0
            l_whence: SEEK_SET
            l_len: 0
       -----------------------------

    release lock by 12398
       -----------------------------
            l_type: F_UNLCK
            l_start: 0
            l_whence: SEEK_SET
            l_len: 0
       -----------------------------

    Close file: hello.c
    [armlinux@lqm fcntl]$ ./fcntl_write
    Open file: hello.c 3
    write lock set by 12399
       -----------------------------
            l_type: F_WRLCK
            l_start: 0
            l_whence: SEEK_SET
            l_len: 0
       -----------------------------

    release lock by 12399
       -----------------------------
            l_type: F_UNLCK
            l_start: 0
            l_whence: SEEK_SET
            l_len: 0
       -----------------------------

    Close file: hello.c

     

    编辑 webmaster

     
     
     
    评论
     
     
    发表
     
    姓名: QQ:
    性别: MSN:
    E-mail: 主页:
    评分: 1 2 3 4 5
    评论内容:
    验证码:
      
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •  
    中国源码网 - www.YuanMa.org - 中国 开放源代码+编程 社区