当多个进程同时访问一个文件的时候,普通的write/read在执行的时候,无法保证 *** 作的原子性,可能会导致文件被污染,达不到预期的结果。
任何一个需要多个函数调用的 *** 作都不可能是原子 *** 作,因为在两个函数调用间,内核可能会将进程挂起执行另外的进程。
如果想要避免这种情况的话,则需要使用pread/pwrite函数
ssize_t pread(int fd ,void *buffer ,size_t size,off_t offset)
返回真正读取到的字节数,offset是指的从文件开始位置起的offset个字节数开始读。其余的参数与read无异。
PS:
pread是无法中断的原子 *** 作,无法中断它的定位和读取 *** 作
pread读取过后的文件偏移量不会发生改变
同理pwrite也是一样的
而在文件创建的时候也是一样的,当需要做文件创建同步的时候,我们需要在O_CREATE的时候,加上O_EXCL标志位,当已经创建过的话,会返回fd,否则返回错误
int dup( int filedes):
传入一个文件描述符,返回当前可用的最小文件描述符。
int dup2(int filedes,int filedes2):
传入文件描述符,以及新的文件描述符,如果新的文件描述符所指向的文件已经打开,则会强行将其关闭后,将该文件描述符指向到已存在的文件描述符。
如果filedes和filedes2指向同一个文件,则不做任何处理,直接返回filedes2,不会关闭文件
新返回回来的filedes2会共享filedes的文件状态标识,文件偏移量等等信息。因为它们的文件指针会指向文件表的同一个位置。只是fd不一样而已。
linux文件编程中的right函数当写入失败时返回值为-1。
在成功的时候,读取的字节数被返回(0表示文件的结束),并且文件位置被这个数字所增加。如果这个数字小于请求的字节数,那就不是一个错误例如,这可能会发生,因为现在实际可用的字节更少可能是因为我们接近文件结束,或者因为我们从管道中读取,或者从终端读取,或者因为read()被一个信号中断了。在错误中,返回-1,并适当地设置errno。
即调用read时,若所要读取的字节数少于文件中的个数,则返回读取到的字节个数;若要读取的个数多于文件中的个数,这不算错误,也返回的是读取到的字节数;若文件为空了,所返回的值即为0;若读取失败,则返回-1。
这里说的文件位置被这个数字增加的意思是你读取一位,指向字节的文件的光标往后移动一位。
read函数实际读到的字节数少于要求读的字节数时:
读普通文件,在读到要求字节数之前就到达文件尾。当从终端设备读。
当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。某些面向记录的设备,如磁带,一次最多返回一个记录。读 *** 作完成后,文件的当前位置将从读之前的位置加上实际读的字节数。当有错误发生时则返回 -1,错误代码存入 errno 中,而文件读写位置则无法预期。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)