unix/linux 进程间文件锁
转自 http://www.cnblogs.com/hjslovewcl/archive/2011/03/14/2314333.html
这里是三个文件锁函数:
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);
}
- g++ lock.c -o 1
- g++ lock2.c -o 2
- 执行两个程序就能看到互斥的效果了
unix/linux 进程间文件锁的更多相关文章
- Linux进程间的通信
一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟 ...
- 利用lsof去查看Unix/Linux进程打开了哪些文件
利用lsof去查看Unix/Linux进程打开了哪些文件 今天用了一下lsof,发现这个linux的小工具,功能非常强大而且好用. 我们可以方便的用它查看应用程序进程打开了哪些文件或者对于特定的一个文 ...
- Linux 进程间通讯方式 pipe()函数 (转载)
转自:http://blog.csdn.net/ta893115871/article/details/7478779 Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道( ...
- PHP与Linux进程间的通信
进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...
- linux进程间的通信方式
linux进程间的通信 进程间的通信就是不同的进程之间传播或交换信息,进程的用户空间是互相独立,进程之间可以利用系统空间交换信息. 管道 允许将一个进程的标准输出和另一个进程的标准输入连接在一起,主要 ...
- Linux 进程间通讯
一.Linux 下进程间通讯方式 1)管道(Pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- Linux 进程间传递文件描述符
文章目录 文件描述符 文件数据结构 共享文件 UNIX域socket实现传递文件描述符 进程间传递打开的文件描述符,并不是传递文件描述符的值.先说一下文件描述符. 文件描述符 对内核来说,所有打开的文 ...
- Linux 进程间通讯详解一
进程间的通讯 两台主机间的进程通讯 --socket 一台主机间的进程通讯 --管道(匿名管道,有名管道) --System V进程间通信(IPC)包括System V消息队列,System V信号量 ...
- linux进程间通讯-System V IPC 信号量
进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的很多其它内容,能够阅读我的还有一篇文章:Linux进程间通信--使用信号.以下就进入信号量的 ...
随机推荐
- C语言之反汇编揭秘
title: 'C语言之反汇编揭秘' tags: 汇编与反汇编 categories: 汇编与反汇编 copyright: true abbrlink: 'b1c9' date: 2019-09-07 ...
- poj 2406 求最短重复字串
题解: KMP中next数组的巧妙运用.在这里我们假设这个字符串的长度是len,那么如果len可以被len-next[len]整除的话,我们就可以说len-next[len]就是那个最短子串的长度为什 ...
- (七)Action之ActionContext(OGNL表达式的使用)
一.ActionContext的重要性 struts中的数据都存放在ActionContext里,所以这部分是Action中的核心. ActionContext又称广义值栈,既然有广义值栈就有侠义值栈 ...
- (一)Redis之简介和windows下安装radis
一.简介 1.1 关于nosql 介绍Redis之前,先了解下NoSQL (Not noly SQL)不仅仅是SQL, 属于非关系型数据库:Redis就属于非关系型数据库, 传统的Mysql ,ora ...
- ASP.NET Core 入门(1)(搭建环境CentOS)
一.CentOS 7 安装 下载CentOS http://isoredirect.centos.org/centos/7/isos/x86_64/ 选择其中下载即可. 下载完成后打开vmware准 ...
- c#基础知识梳理(二)
上期回顾 - https://www.cnblogs.com/liu-jinxin/p/10818256.html 一.变量 一个变量只不过是一个供程序操作的存储区的名字.在 C# 中,每个变量都有一 ...
- mysql8中查询语句表别名不能使用 “of”
今天在迁移一个项目的时候,发现有一个sql报错,但是语句跟迁移之前完全一样,所以想来应该是 mysql 版本差异导致的. 迁移之前版本:5.6.28(腾讯云) 迁移之后版本:8.0.16(阿里云) 新 ...
- Unity 宽度适配 NGUI
这是很久之前写的一篇Note,现在移到Blog上来,可能有些参数,NGUI插件等等不和现在版本相同.不过大概的思路应该不会错. ps: 可能有部分內容是摘抄自其他作者,没办法考证了,如有请务必联系我. ...
- python多线程与多进程异步事件框架
多线程简单实现 #!/usr/bin/env python # -*- coding: UTF-8 -*- import logging import queue import threading f ...
- Flutter——Expanded组件("可伸缩"组件)
Expanded组件可以结合Row和Column布局组件使用. Expanded组件的常用属性 属性 说明 flex 元素占整个父Row/Column的比例 child 子元素 import 'pac ...