Bog*_*tyr 5 c++ linux concurrency multithreading file
我想知道Linux读/写系统调用是否支持从多个线程或进程对单个磁盘文件的非重叠区域进行非同步的读/写(非附加写)。每个线程将查找文件自己的区域,并以独占方式访问该区域,而不会与其他线程正在操作的区域重叠。
我想知道 linux 读/写系统调用是否支持从多个线程或进程对单个磁盘文件的非重叠区域进行非同步读/写(非附加写入)。每个线程将寻找它自己的文件区域,并专门从/向该区域读/写,永远不会与其他线程正在操作的区域重叠。
POSIX 在XSH 2.9.7中规定,基本上所有 I/O 函数在 POSIX 指定的效果方面都是原子的。对其中适用的具体功能一长串,并给出open(),lseek(),read(),write(),和close()都是它。所以,
如果两个线程分别调用这些函数中的一个,则每个调用要么看到另一个调用的所有指定效果,要么不看到它们。
这不依赖于任何外部同步,即使是对与相同打开文件描述相关联的文件描述符的操作。
同一个文件可以有多个打开的文件描述,即使在一个进程中也是如此(例如,参见open(2)的手册页)。鉴于多个线程在同一常规文件的非重叠区域上执行read()和write()操作,通过引用不同打开文件描述的文件描述符,POSIX 不提供期望这些操作相互干扰的基础,无论所涉及线程的外部同步如何。在实践中,它运行良好。
如果所涉及的线程试图使用引用相同打开文件描述的文件描述符,那么您可能会遇到麻烦。这些不必是相同的文件描述符值(因此dup()在此处使用文件描述符无济于事),线程也不必属于同一进程以出现这种情况。每个打开的文件描述都有一个关联的文件位置,所以如果两个不同的线程试图执行每个都需要单独设置文件偏移量和向文件传输数据或从文件传输数据的任务,并且如果它们使用相同的打开文件描述,那么单个函数调用的原子性不足以确保在预期位置执行读取和写入。在这种情况下需要同步。
或者,正如@maximegorushkin 在评论中和@bk2204 在另一个答案中所观察到的那样,pread()和pwrite()函数在一次调用中执行定位和数据传输。这些也在原子 I/O 函数列表中,它们克服了基于每个数据传输的定位与数据传输的分离。使用它们需要额外的小心和簿记,并且在某些情况下它不能充分服务,但对于所讨论的特定情况它可能仍然可行。
因此,如果两个不同的线程想要在不同步的情况下对同一个文件进行操作,那么最安全和最通用的方法是让每个线程独立打开文件。只要它们的 I/O 操作仅限于文件的不相交区域,它们就不会相互干扰。即使对文件的重叠区域进行操作也不是不可能的,但这会引入更复杂的、特定于应用程序的注意事项。