如何將Linux包含flock的程式移植到Solaris

來源:互聯網
上載者:User

如何將包含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宏的定義所致。

但是,朋友查了solaris的man,確信已經正確的include了標頭檔,下面是solaris man手冊的說明:朋友已經grep了/usr/include/sys/file.h確實沒有發現LOCK_EX宏的定義。難道真的是solaris的標頭檔出了問題?

從flock(3UCB)可以看出,該調用是屬於man手冊的section 3的3UCB字類中,
讓我們看看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, 0, sizeof (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

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.