转自 http://www.cnblogs.com/hjslovewcl/archive/2011/03/14/2314333.html

有三种不同的文件锁,这三种都是“咨询性”的,也就是说它们依靠程序之间的合作,所以一个项目中的所有程序封锁政策的一致是非常重要的,当你的程序需要和第三方软件共享文件时应该格外地小心。有些程序利用诸如 FIlENAME.lock 的文件锁文件,然后简单地测试此类文件是否存在。这种方法显然不太好,因为当产生文件的进程被杀后,锁文件依然存在,这样文件也许会被永久锁住。UUCP 中把产生文件的进程号PID存入文件,但这样做仍然不保险,因为PID的利用是回收型的。
这里是三个文件锁函数:
     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 <fcntl.h>;
#include <unistd.h>; 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 = ;
ret.l_whence = whence ;
ret.l_len = ;
ret.l_pid = getpid() ;
return &ret ;
}
 
//lock.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
struct flock* file_lock(short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = ;
ret.l_whence = whence;
ret.l_len = ;
ret.l_pid = getpid();
return &ret;
}
int main()
{
int fd = open("1.txt", O_WRONLY|O_APPEND);
for(int i=; i<; ++i) {
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
char buf[] = {};
sprintf(buf, "hello world %d/n", i);
int len = strlen(buf);
write(fd, buf, len);
fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
sleep();
}
close(fd);
}
//lock2.c...同lock.c相比只是修改了下buf内容
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
struct flock* file_lock(short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = ;
ret.l_whence = whence;
ret.l_len = ;
ret.l_pid = getpid();
return &ret;
}
int main()
{
int fd = open("1.txt", O_WRONLY|O_APPEND);
for(int i=; i<; ++i) {
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
char buf[] = {};
sprintf(buf, "china %d/n", i);
int len = strlen(buf);
write(fd, buf, len);
fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
sleep();
}
close(fd);
}
  1. g++ lock.c -o 1
  2. g++ lock2.c -o 2
  3. 执行两个程序就能看到互斥的效果了

unix/linux 进程间文件锁的更多相关文章

  1. Linux进程间的通信

    一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟 ...

  2. 利用lsof去查看Unix/Linux进程打开了哪些文件

    利用lsof去查看Unix/Linux进程打开了哪些文件 今天用了一下lsof,发现这个linux的小工具,功能非常强大而且好用. 我们可以方便的用它查看应用程序进程打开了哪些文件或者对于特定的一个文 ...

  3. Linux 进程间通讯方式 pipe()函数 (转载)

    转自:http://blog.csdn.net/ta893115871/article/details/7478779 Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道( ...

  4. PHP与Linux进程间的通信

    进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...

  5. linux进程间的通信方式

    linux进程间的通信 进程间的通信就是不同的进程之间传播或交换信息,进程的用户空间是互相独立,进程之间可以利用系统空间交换信息. 管道 允许将一个进程的标准输出和另一个进程的标准输入连接在一起,主要 ...

  6. Linux 进程间通讯

    一.Linux 下进程间通讯方式 1)管道(Pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  7. Linux 进程间传递文件描述符

    文章目录 文件描述符 文件数据结构 共享文件 UNIX域socket实现传递文件描述符 进程间传递打开的文件描述符,并不是传递文件描述符的值.先说一下文件描述符. 文件描述符 对内核来说,所有打开的文 ...

  8. Linux 进程间通讯详解一

    进程间的通讯 两台主机间的进程通讯 --socket 一台主机间的进程通讯 --管道(匿名管道,有名管道) --System V进程间通信(IPC)包括System V消息队列,System V信号量 ...

  9. linux进程间通讯-System V IPC 信号量

    进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的很多其它内容,能够阅读我的还有一篇文章:Linux进程间通信--使用信号.以下就进入信号量的 ...

随机推荐

  1. ActiveMQ的静态网络配置

    static networkConnector是用于创建一个静态的配置对于网络中的多个Broker做集群,这种协议用于复合url,一个复合url包括多个url地址. <networkConnec ...

  2. javascript 写一个ajax 自动拦截,并下载数据

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  3. css 动画(二) transition 过渡 & animation 动画

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! translate:平移:是transform的一个属性: transform:变形:是一个静态属性,可以 ...

  4. (三)mybatis之通过接口加载映射配置文件

    1.1  需求 通过(二)在全局配置文件 mybatis-configuration.xml 通过 <mappers> 标签来加载映射文件,那么如果我们项目足够大,有很多映射文件呢,难道我 ...

  5. 前端开发 Vue -1windows环境搭建Vue Node开发环境

    解决几个疑问: 想学习下vue.js,我理解的它是一个前端的框架,主要作用是对数据的处理,和juqery类似,所以不太理解为什么要在nodejs中npm install vue呢?在html文件中引入 ...

  6. jQuery_了解jQuery

  7. Java中常见时间类的使用

    模拟场景针对于常用的操作API,比如流操作(字符流.字节流),时间操作等,仅仅了解概念性的定义终究是无法了解该类的用途和使用方式:这种情况在使用的时候便一脸茫然,脑海中映射不到对应的知识点.本篇博客将 ...

  8. PHP函数问题

    有时候,运行nginx和PHP CGI(PHP FPM)web服务的Linux服务器,突然系统负载上升,用top命令查看,很多phpcgi进程的CPU利用率接近100%后来通过跟踪发现,这种情况与PH ...

  9. [LeetCode] 219. Contains Duplicate II ☆(存在重复元素2)

    每天一算:Contains Duplicate II 描述 给出1个整形数组nums和1个整数k,是否存在索引i和j,使得nums[i] == nums[j] 且i和j之间的差不超过k Example ...

  10. STM32窗口看门狗WWDG库函数的一点思考

    WWDG当前计数器的值以及激活位和WWDG_CR这个寄存器相关.如下图所示: 而STM32f10x的库函数提供了两种设置WWDG_CR[0:6]位的方式. WWDG_SetCounter方法 #def ...