读写相关的问题是永远存在的,文件锁就是为了解决这个问题而做的,其实它就是个简单的信号量。读写相关性指由于同时读写文件造成文件数据的随机性冲突。为了明确知道在何时通过何种操作对更改或是读取了文件中的那些数据,有必要对操作进行序列化,原子化,同步化,使用户能确知在何时文件中有什么数据。文件锁就是其中一个工具。
文件系统一般有两种锁,共享锁及排它锁,也可被称为读锁和写锁。
文件系统锁的特点:
一个文件打开的时候只能拥有一把锁,就是说在同时,不能给一个文件同时分配两把以上的锁。
读写已被上锁的文件的用户可以持有这把锁,即持有这把锁的用户可以对该文件进行相应的操作,如读或写。用户可以申请持有某个文件锁,如果文件开始无锁,申请持有锁之前先由系统为该文件创建了一把锁,然后该申请者持有它。
持有锁的规则:如果这个文件已拥有一个读(共享)锁,其它用户不能为该文件分配排它锁或只读锁,但可以持有这把锁,也就是说其它用户可以读文件,但只要该文件被锁住,就没有用户可以对其进行写入。如果该文件已有一把排它锁且已为某用户持有,则没有任何用户可以再持有这把锁,除非持有者解锁。
有一个重要的概念要记住:对文件的操作本身与锁其实没有什么关系,无论文件是否被上锁,用户都可以随意对文件进行正常情况下的任何操作,但操作系统会检查锁,针对不同的情况给予不同的处理。比如说在无锁的情况下,任何人可以同时对某文件进行任意的读写,当然这样很有可能读写的内容会出现错误——注意只是内容出错,操作并不会出错。加锁后,某些操作在某些情况下会被拒绝。文件锁的作用并不是保护文件及数据本身,而是保证数据的同步性,因此文件锁只对持有锁的用户才是真正有效的,也只有所有用户都使用同一种完全相同的方式利用文件锁的限制对文件进行操作,文件锁才能对所有用户有效,否则,只要有一个例外,整个文件锁的功能就会被破坏。比如,所有人都遵循的开文件,加锁,操作读写,解锁,关闭文件的步骤的话,所有的人操作都不会出现问题,因为基于文件锁的分配及持有原则,文件中的数据的更新是作为原子操作存在的,是不可分的,因此也是同步的,安全的。但假如某个人不是采取此步骤,那么他在读写时就会出现问题,不是读不准就是写不进等等。
基于以上原理,对读数据是否锁定这点就值得说说。一般来说,写数据的时候排它锁定是唯一的操作,它这时保证写到文件中的数据是正确的,文件被锁时,其它用户无法得到该锁,因此无权做任何操作。在读的时候,要视具体情况而定,大多数情况下,如果不需要特别精确或是敏感的数据,无需锁定,因为锁定要花时间和资源,一个人申请持有锁花不了时间,人一多就有问题了,最主要的是,如果该文件需要被更新的话,假如被上了只读锁,则写入无法进行,因为那些想写入的用户将得不到排它锁,如果同时申请持有只读锁的人过多的话,排它锁就有可能一直申请不到,这样表现就是文件可能很长时间内无法被写入,显得很慢。一般来说,写文件的机会相对较少,也更重要,因此主要做好排它锁定,只读锁在多数情况下并无必要。那么只读锁用在何处呢?只读锁其实只对用户本身有用,只读锁保证用户读到的数据是确实从文件中读到的真实数据,而不是被称为“dirty”的脏数据。其实,这个还是针对那些不用锁的其它用户对文件的误操作,假如文件上锁,其它用户不一定非要通过锁对文件进行读写,如果他是直接读写的话,对上了锁的文件操作不一定有效,持有读锁的用户可以肯定在他读数据的时候读出来的是从真实的文件中得到的,而不是同时已被覆盖掉的数据。
因此,在写入的时候上排它锁应该是天经地义的,可以保证这时数据的不会出错。如果你不申请共享锁,可能读出的数据有错误,但对文件本身没有任何影响,影响只是对用户的,申请共享锁后读出的数据肯定是当时读的时候文件中的真实数据,如果不是为了保证数据的精确性,共享锁可以不加,充其量就是重新读一次,如果你读它是为了写入,不如直接加排它锁,没有必要用共享锁。
还有一点要强调的是:文件锁只对使用它的用户,而且是按规则使用它的用户才有效,否则,你用你的,我用我的,有的用,有的不用,还是会乱套的,错误还是会出现的,对同一个文件,只有大家用同一个规则用文件锁,才能保证每个用户在对该文件进行共享操作的时候不会出现读写错误。
以上是就本人知识说的一点原理,可能有些错漏,如有需要更正的,还请多指教。(http://bbs.chinaunix.net/viewthread.php?tid=255335)
分享到:
相关推荐
- 写入循环:使用`写到文件`命令,配合循环将数据写入文件,记录每次写入的时间或字节数。 - 性能计算:根据写入时间和数据量,计算平均写入速度。 - 文件关闭:使用`关闭文件`命令,确保数据正确保存并释放资源...
本案例中,“缓存List并写入文件持久化”的主题聚焦于如何将内存中的数据,特别是列表(List)类型,存储到文件中,以实现数据的长期保存。下面我们将详细探讨这个过程,包括相关技术、步骤以及最佳实践。 首先,...
本文将深入探讨标题为“行业分类-设备装置-一种适应于多路并发写入流媒体数据的分块式存储算法”的技术主题,结合描述与提供的PDF文档,我们将详细解析这一算法的核心原理及其在实际应用中的价值。 首先,我们要...
在本文中,我们将深入探讨如何使用C#中的`HttpListener`类来构建一个简单的高并发HTTP服务器。`HttpListener`是.NET Framework提供的一个强大的组件,它允许开发者创建一个能够监听和响应HTTP请求的服务。我们将讨论...
6. **替代方案**:除了优化RRD,还可能探讨了其他时间序列数据库,如InfluxDB或OpenTSDB,这些系统可能更适合处理高并发写入场景。 7. **测试与性能基准**:博主可能进行了详尽的测试,包括模拟大量并发写入,记录I...
本主题将深入探讨如何使用Delphi实现高速、高并发的数据库访问,并以"UDBSyncMng.pas"这个文件作为核心组件来展开讨论。 1. **Delphi与数据库接口** Delphi是一款强大的RAD(快速应用开发)工具,内置了对多种...
LinuxC高并发服务器是利用操作系统提供的epoll机制,在C语言环境下构建的一种能处理大量并发连接的服务器。Epoll是Linux内核提供的一种I/O多路复用技术,它极大地提升了在高并发场景下的系统性能。下面我们将深入...
本文将详细探讨如何构建能够支持高并发和高负载的大型网站系统架构。 #### 一、高性能服务器的选择 高性能服务器是支撑大规模网站的基础。选择合适的硬件配置非常重要,包括但不限于: - **CPU**:多核处理器可以...
- **并发处理**:通过多线程或异步操作,可以在读取或写入文件流时并行处理不同部分,提升整体性能。 - **流式读写器**:NPOI提供了一些流式接口,如`SheetInputStream`和`RowOutputStream`,允许更细粒度的控制数据...
首先,我们要明确在多线程环境中直接并发写入同一文件可能导致的问题。如果多个线程同时写入文件,可能会导致数据交错、丢失或文件损坏。为了解决这个问题,我们需要引入一种机制来确保同一时间只有一个线程能够访问...
在不同的场景下,文件的写入操作可能需要考虑的因素包括:顺序写入与随机写入、文件的追加模式、缓冲策略以及并发写入的同步机制等。在主电路板和CPU层面,这些操作需要考虑到硬件的特性,如内存带宽、处理器指令集...
然后,向文件中写入指定的字符串,并读取文件内容显示在网页上。 ##### 关键步骤: 1. **定义写入内容**: - `String str="var ajaxobj=new AJAX;failmode=false";` 定义了待写入的字符串。 2. **获取文件路径**...
同步读写是指在执行I/O操作(如读取或写入文件)时,程序会暂停当前的执行流程,等待I/O操作完成后再继续。这种方式保证了数据的准确性和顺序性,但可能会造成阻塞,即CPU在等待I/O操作时无法执行其他任务,降低了...
在C#中,可以将读取的文本文件内容填充到datagridview中: ```csharp // 假设content是从文件读取的字符串,每行是CSV格式 string[] lines = content.Split('\n'); dataGridView1.Rows.Clear(); foreach ...
它提供了一种方便的方式来读取和写入文件内容。在不同的编程语言中,文件流的实现方式略有不同: - **C++**: 使用 `<fstream>` 库中的 `ifstream`(输入文件流)和 `ofstream`(输出文件流)类。 - **Java**: 使用 ...
例如,50线程并发写入1G文件时,耗时高达388870毫秒,这表明在极高并发情况下,FastDFS可能会面临性能瓶颈。 综上所述,HDFS并不适合需要高并发读写操作的实时应用,其性能更适用于大数据分析和离线计算。而FastDFS...
7. **并发写入**:如果多个进程同时尝试写入同一INI文件,可能会导致数据冲突或损坏。应考虑使用锁或其他同步机制来避免这种情况。 在Python源码中,你可能会看到各种处理这些限制的方法,例如通过异常处理来捕获并...
NIO能够以更有效的方式管理系统资源,特别是在高并发环境中。此外,通过缓冲区和选择器,可以提高I/O操作的吞吐量。 总结,Java NIO提供了一套高效、灵活的文件写入机制,包括通道、缓冲区、内存映射文件和选择器等...
5. 文件的创建、读取、写入和追加:C#提供了`File`类,包含`Create()`, `ReadAllText()`, `WriteAllText()`, `AppendAllText()`等方法,分别用于创建新文件、读取文件内容、写入文本到文件以及在文件末尾追加文本。...