_sopen_s如何管理对同一文件的多次写入

How does _sopen_s manage multiple writing to same file

本文关键字:文件 sopen 何管理 管理      更新时间:2023-10-16

我有一个c++应用程序,它处理多个连接并写入文件。当使用函数_sopen_s和参数_SH_DENYNO时,所有同时工作的线程都在文件中写入,我看到没有数据丢失。你能告诉我该函数是如何管理对文件的访问的,这样就不会丢失数据了吗?

亲切的问候

如果您正在使用write(),或者它的一些操作系统提供的变体,则单个write()调用往往被实现为每个对write()的调用都是原子的,因为关于write()的这个POSIX语句的含义:

在普通文件或其他能够查找的文件上,实际写入所有数据应从文件中指定的位置开始与字段相关联的文件偏移量。在成功返回之前Write()时,文件偏移量应按字节数递增写。在常规文件上,如果此增量文件偏移量大于文件的长度,文件的长度应该是多少设置为文件偏移量

这在某种程度上很难实现,允许来自同一文件描述符上的单独write()调用的交错数据,因为如果数据是交错的,完成时文件偏移量的变化将不等于"实际写入的字节数"。因此,该语句可以被解释为对任何"常规文件或其他能够查找的文件"的write()调用的原子性的隐含要求。

此外,还有显式POSIX要求write()调用小于或等于PIPE_BUF字节的管道是原子的:

原子性/非原子性:如果在一个操作中写入的全部数据不与任何其他进程的数据交叉,则写入是原子性的。当有多个写入器向对象发送数据时,这很有用单一的读者。应用程序需要知道写请求可以有多大期望自动执行。这个最大值叫做{PIPE_BUF}。POSIX.1-2008本卷没有说明是否写入超过{PIPE_BUF}字节的请求是原子的,但需要这样做{PIPE_BUF}或更少字节的写入应该是原子的。

由于write()只获得文件描述符的int,而没有其他关于文件描述符引用的直接可用信息,因此以满足POSIX对管道原子write()的要求的方式实现write()的最简单方法是使每个write()调用原子。

因此,尽管对于原子性没有要求,除非您向实际管道写入少于或等于PIPE_BUF字节,但write()倾向于为所有内容自动实现。

现在,这并不意味着无论文件描述符指向什么都不会破坏数据或将其与其他数据交叉。例如,如果两个线程分别尝试调用一个write()操作来同时将几GB的数据从MPEG文件流式传输到同一个TCP套接字,那么看到交错的数据我一点也不会感到惊讶。

你实际上并没有调用write()。但是底层实现很可能是共享的