转自 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. Go学习路径--相关基础

    现在开始接触Go一段时间了,基本路径就是看基础学习材料,开始写项目,有问题找解决问题的方法.这里记录一下学习过程. go相关文章 Golang适合高并发场景的原因分析 go build 不同系统下的可 ...

  2. 普通表分区改造_rename方式

    一.需求 配合开发人员,对业务临时表进行分区改造(业务认为的临时表,只需要保留近一月数据,并非oracle临时表类型) 二.如下记录完整过程 开发需求 TS_PM 以time_key分区 .沟通明确方 ...

  3. sftp配置多个用户权限的问题

    groupadd group1 chmod 0755 /test/useradd -g group1 -d /test/backend/ -M test_backendusermod -s /sbin ...

  4. luogu2657-Windy数题解--数位DP

    题目链接 https://www.luogu.org/problemnew/show/P2657 分析 第一道数位DP题,发现有点意思 DP求\([L,R]\)区间内的XXX个数,很套路地想到前缀和, ...

  5. Java 之 IDEA 的 Debug 追踪

    使用 IDEA 的断点调试功能,查看程序的运行过程. 1.在有效代码行,点击行号右边的空白区域,设置断点,程序执行到断点将停止,我们可以手动来运行程序 2.点击 Debug 运行模式 3.程序停止在断 ...

  6. swoole httpserver学习

    文件 HttpServer.php <?php /** * Created by PhpStorm. * User: mac * Date: 2019/9/13 * Time: 21:00 */ ...

  7. vscode-golang跳转定义无效问题

    问题发现: 本来可以进行"ctrl"+点击或者F12,进行跳转定义的方式,突然失效了 问题分析: 1.辅助工具是否关闭 解决方案,进入首选项,设置,查找go.docsTool,选项 ...

  8. 【Distributed】分布式配置中心

    一.概述 1.1 什么是分布式配置中心 常用分布式配置中心框架 二.Apollo阿波罗 2.1 Apollo特点 2.2 Apollo整体架构原理 2.3 Apollo Portol 环境搭建 Lin ...

  9. django启动通过ip或是域名访问

    setting.py里面的ALLOWED_HOSTS = ['localhost','域名','本机ip'] 启动时一般都是命令行 python manage.py runserver [端口号]  ...

  10. Mybatis报错: There is no getter for property named xxx

    在mapper文件中函数的形参上加上注解. 例如: 出现了如下错误:核心错误提示就是There is no getter for property named xxx     ### Error qu ...