• 如何将Linux包含flock的程序移植到Solaris


    如何将包含flock的程序移植到Solaris

    作者: Badcoffee
    Email: blog.oliver@gmail.com
    Blog: http://blog.csdn.net/yayong
    20055

    一个朋友的Linux源程序中包含如下调用:

    flock(fd, LOCK_UN)

    Linux上用gcc编译没有问题。但在Solaris上编译时,出错:error: `LOCK_EX' undeclared (first use in this function)
    显然,这是因为没有include正确的头文件,导致无法找到LOCK_EX宏的定义所致。

    但是,朋友查了solarisman,确信已经正确的include了头文件,下面是solaris man手册的说明:朋友已经grep/usr/include/sys/file.h确实没有发现LOCK_EX宏的定义。难道真的是solaris的头文件出了问题?

    flock(3UCB)可以看出,该调用是属于man手册的section 33UCB字类中,
    让我们看看3UCB是干什么用的:问题得到解决,原来3UCB的函数是为兼容BSD函数而保留下来的,果然按照说明,在/usr/ucbinclude/sys/file.h中找到了这个宏。

    通过这么一查,发现section 3里的子类真的很多,以后查man的时候一定要留心。

    man flock

    SunOS
    /BSD Compatibility Library Functions flock(3UCB)

    NAME
    flock 
    - apply or remove an advisory lock on an open file

    SYNOPSIS
    /usr/ucb/cc[ flag ... ] file ...
    #include sys
    /file.h

    int flock( fd, operation);
    int fd, operation;

    下面是常用的文件锁函数说明:

    flock(); 
    lockf(); 
    fcntl();

    flock()是从BSD中衍生出来的,但目前在大多数UNIX系统上都能找到,在单个主机上flock()简单有效,但它不能在NFS上工作。

    Perl中也有一个有点让人迷惑的 flock()函数,但却是在perl内部实现的。 fcntl()是唯一的符合POSIX标准的文件锁实现,所以也是唯一可移植的。它也同时是最强大的文件锁——也是最难用的。

    在NFS文件系统上,fcntl()请求会被递交给叫rpc.lockd的守护进程,然后由它负责和主机端的lockd对话,和flock() 不同,fcntl()可以实现记录层上的封锁。 lockf()只是一个简化了的fcntl()文件锁接口。无论你使用哪一种文件锁,请一定记住在锁生效之前用sync来更新你所有的文件输入/输出。

    lock(fd);
    write_to(some_function_of(fd));
    flush_output_to(fd); 
    /* 在去锁之前一定要冲洗输出 */
    unlock(fd);
    do_something_else;  
    /* 也许另外一个进程会更新它 */
    lock(fd);
    seek(fd, somewhere); 
    /* 因为原来的文件指针已不安全 */
    do_something_with(fd);
     ...

    一些有用的fcntl()封锁方法(为了简洁略去错误处理):

    #include 
    #include 
    read_lock(
    int fd)  /* 整个文件上的一个共享的文件锁 */
    {
        fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET));
    }

    write_lock(
    int fd) /* 整个文件上的一个排外文件锁 */ 
    {
        fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));  
    }

    append_lock(
    int fd) /* 一个封锁文件结尾的锁, 其他进程可以访问现有内容 */   
    {
        fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_END));
    }

    前面所用的file_lock函数如下:

    struct flock* file_lock(short type, short whence)
    {
        
    static struct flock ret ;
        ret.l_type 
    = type ;
        ret.l_start 
    = 0 ;
        ret.l_whence 
    = whence ;
        ret.l_len 
    = 0 ;
        ret.l_pid 
    = getpid() ;
        
    return &ret ;
    }

    而且根据solaris flock(3UCB)的说明,该函数不是线程安全的,因此,强烈建议用fcntl来取代flock,毕竟它才是POSIX的标准。

    另外,对于很多大容量邮件系统的应用,邮箱是通过NFS共享的,更不能用flock来做了。在Solaris上, 可以使用下面的代码来实现一个新的flock:

    #ifndef LOCK_SH
    #define   LOCK_SH   1    /* shared lock */
    #define   LOCK_EX   2    /* exclusive lock */
    #define   LOCK_NB   4    /* don't block when locking */
    #define   LOCK_UN   8    /* unlock */
    #endif
    #ifdef POSIX
    #include 
    /*
     * This function emulates a subset of flock()
     
    */
    int emul_flock(fd, cmd)
        
    int fd, cmd;
    {    
    struct flock f;
        memset(
    &f, 0sizeof (f));
        
    if (cmd & LOCK_UN)
            f.l_type 
    = F_UNLCK;
        
    if (cmd & LOCK_SH)
            f.l_type 
    = F_RDLCK;
        
    if (cmd & LOCK_EX)
            f.l_type 
    = F_WRLCK;
        
    return fcntl(fd, (cmd & LOCK_NB) ? F_SETLK : F_SETLKW, &f);
    }
    #define flock(f,c)      emul_flock(f,c)
    #endif
  • 相关阅读:
    ConcurrentHashMap
    Linux中如何开启8080端口供外界访问 和开启允许对外访问的端口8000
    CentOs 7 Linux系统下我的/etc/sysconfig/路径下无iptables文件
    CentOS7开启SSH服务
    Centos7下Samba服务器配置
    CentOS7(Linux)网络yum源配置
    Linux(Centos7)中配置Java环境变量
    SpringAOP-什么是面向切面编程?
    Swagger Demo
    自定义个Bean名称生成策略, 解决不同包下同名类问题/AnnotationBeanNameGenerator
  • 原文地址:https://www.cnblogs.com/ainima/p/6330843.html
Copyright © 2020-2023  润新知