完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转载出处:http://blog.csdn.net/cywosp/article/details/30083015 1. 场景概述 在多线程开发中,互斥锁可以用于对临界资源的保护,防止数据的不一致,这是最为普遍的使用方法。那在多进程中如何处理文件之间的同步呢?我们看看下面的图: 图中所示的是两个进程在无同步的情况下同时更新同一个文件的过程,其主要的操作是: 1. 从文件中读取序号。从图中可得知两个进程读取分别增加了所读取到的序号,并写回到了文件中,但是如果有相互互斥的话,最后的值应该是1002,而不是所示的1001。为了防止出现这种情况,Linux提供了flock(对整个文件加锁)、fcntl(对整个文件区域加锁)两个函数来做进程间的文件同步。同时也可以使用信号量来完成所需的同步,但通常使用文件锁会更好一些,因为内核能够自动将锁与文件关联起来。 2. flock() flock的声明如下 #includefcntl()函数提供了比该函数更为强大的功能,并且所拥有的功能也覆盖了flock()所拥有的功能,但是在某些应用中任然使用着flock()函数,并且在继承和锁释放方面的一些语义 中flock()与fcntl()还是有所不同的。 flock()系统调用是在整个文件中加锁,通过对传入的fd所指向的文件进行操作,然后在通过operation参数所设置的值来确定做什么样的操作。operation可以赋如下值: 在默认情况下,如果另一个进程已经持有了文件上的一个不兼容的锁,那么flock()会阻塞。如果需要防止这种情况的出现,可以在operation参数中对这些值取OR(|)。在这种情况下,如果一个进程已经持有了文件上的一个不兼容锁,那么flock()就会阻塞,相反,它会返回-1,并将errno设置成EWOULDBLOCK。 任意数量的进程可同时持有一个文件上的共享锁,但子任意时刻只能有一个进程能够持有一个文件上的互斥锁,(这有点类似读写锁)。下图是进程A先设置了锁,进程B后设置锁的支持情况: 无论程序以什么模式打开了文件(读、写或者读写),该文件上都可以放置一把共享锁或互斥锁。在实际操作过程中,参数operation可以指定对应的值将共享锁转换成互斥锁(反之亦然)。将一个共享锁转换成互斥锁,如果另一个进程要获取该文件的共享锁则会阻塞,除非operation参数指定了LOCK_NB标记,即:(LOCK_SH | LOCK_NB)。锁的转换过程不是一个原子操作,在转换的过程中首先会删除既有的锁,然后创建新锁。 3. 锁继承与释放的语义 flock()根据调用时operation参数传入LOCK_UN的值来释放一个文件锁。此外,锁会在相应的文件描述符被关闭之后自动释放。同时,当一个文件描述符被复制时(dup()、dup2()、或一个fcntl() F_DUPFD操作),新的文件描述符会引用同一个文件锁。 flock(fd, LOCK_EX);这段代码先在fd上设置一个互斥锁,然后通过fd创建一个指向相同文件的新文件描述符new_fd,最后通过new_fd来解锁。从而我们可以得知新的文件描述符指向了同一个锁。所以,如果通过一个特定的文件描述符获取了一个锁并且创建了该描述符的一个或多个副本,那么,如果不显示的调用一个解锁操作,只有当文件描述符副本都被关闭了之后锁才会被释放。 由上我们可以推出,如果使用fork()创建一个子进程,子进程会复制父进程中的所有描述符,从而使得它们也会指向同一个文件锁。例如下面的代码会导致一个子进程删除一个父进程的锁: flock (fd, LOCK_EX);所以,有时候可以利用这些语义来将一个文件锁从父进程传输到子进程:在fork()之后,父进程关闭其文件描述符,然后锁就只在子进程的控制之下了。通过fork()创建的锁在exec()中会得以保留(除非在文件描述符上设置了close-on-exec标记并且该文件描述符是最后一个引用底层的打开文件描述的描述符)。 如果程序中使用open()来获取第二个引用同一个文件的描述符,那么,flock()会将其视为不同的文件描述符。如下代码会在第二个flock()上阻塞。 fd1 = open ("test.txt", O_RDWD);4. flock()的限制 flock()放置的锁有如下限制
注释:在默认情况下,文件锁是劝告式的,这表示一个进程可以简单地忽略另一个进程在文件上放置的锁。要使得劝告式加锁模型能够正常工作,所有访问文件的进程都必须要配合,即在执行文件IO之前先放置一把锁。 |
|
相关推荐
|
|
你这个是应用程序的锁吧。
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
「含关键代码」基于AM3352/AM3354/AM3359的Linux开发案例分享
4885 浏览 0 评论
87391 浏览 0 评论
【高手问答】如何做到精通linux技术?资深工程师带你突破难点
4710 浏览 2 评论
3602 浏览 2 评论
解读Linux :先从创建一个文件夹用来存放jdk压缩文件开始
2469 浏览 0 评论
1987浏览 3评论
1259浏览 1评论
求解:aarch64交叉编译工具已经安装成功,环境变量已经配置,怎么将系统架构切换为ARM的架构
1332浏览 0评论
电脑和虚拟机可以互ping,电脑和开发板也可以互ping,但是虚拟机和开发板ping不通是什么原因
1226浏览 0评论
1166浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-11 23:10 , Processed in 0.941581 second(s), Total 45, Slave 35 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号