C read()线程安全吗? [英] Is C read() Thread Safe?

查看:411
本文介绍了C read()线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序,其中多个线程可能同时从一个文件读取.没有线程正在写入文件,但是它们可能各自将其内容复制到单独的内存段中.

I'm writing a program where multiple threads might read from a file simultaneously. No threads are writing to the file, but they might each copy its contents to separate memory segments.

要实现此目的,我需要使用一个API,该API为我要读取的文件提供了文件描述符.我正在使用C的 read 函数读取文件的大部分.手册页说:成功后,将返回读取的字节数(零表示文件结束),并且文件位置以该数字前移."但是,关于文件位置的提升是否是线程安全的,我找不到任何确定的信息.

To do implement this, I'm required to use an API that gives me a file descriptor for the file I want to read. I'm reading chunks of the file with C's read function. The man page says that, "On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number." I can't find any definitive information, though, on whether or not the advancement of the file position is thread safe.

说我有线程T1和线程T2一次读取文件的1个字节.如果read()是线程安全的,则可能会出现以下情况:

Say I have thread T1 and thread T2 reading 1 byte of the file at a time. If read() is thread-safe, I would expect the following:

T1: read() => file position == 1
T2: read() => file position == 1
T1: read() => file position == 2
T2: read() => file position == 2
...

但是我担心,如果它不是线程安全的,那么可能会发生以下情况:

But I'm worried that if it's not thread-safe, then the following could happen:

T1: read() => file position == 1
T2: read() => file position == 2
T1: read() => file position == 3
T2: read() => file position == 4
...

如果有帮助,每个线程将使用相同的文件描述符.换句话说,是使用open()打开文件的API.然后,正在读取文件的线程根据客户端请求获取该文件描述符.如果每个线程都存储有关文件位置的信息,那应该没问题.我只是找不到有关什么位置的文件信息,以及read()在哪里弄清楚它的位置.

If it helps, each thread would be using the same file descriptor. In other words, it's the API that opens the file using open(). The threads that are reading the file then fetch that file descriptor based on a client request. If each thread stores its own information about the file position, then it should be fine. I just can't find any information on what holds the file position, and where read() figures out what it is.

推荐答案

read本身是线程安全的,但这并不一定意味着您要执行的操作都是线程安全的.根据POSIX( 2.9.7具有常规文件操作的线程交互) :

read itself is thread-safe, but that doesn't necessarily mean the things you want to do with it are thread-safe. Per POSIX (2.9.7 Thread Interactions with Regular File Operations):

以下所有功能在对常规文件或符号链接进行操作时,在POSIX.1-2008中指定的效果中,彼此之间应是原子的:

All of the following functions shall be atomic with respect to each other in the effects specified in POSIX.1-2008 when they operate on regular files or symbolic links:

...

(read在下面的列表中.)

此外,这意味着读取数据和前进当前文件位置相对于彼此是原子的,并且读取的每个字节将被精确读取一次.但是,还有其他一些考虑因素可能会使您的事情复杂化,尤其是:

Among other things, this means that reading the data and advancing the current file position are atomic with respect to each other, and each byte that's read will be read exactly once. However, there are other considerations that can complicate things for you, especially:

  • 短读取:read(fd, buf, n)不需要读取n字节.它可以读取1到n字节之间的任意位置,并且当您再次调用它以读取其余字节时,相对于第一个字节,第二个读取不再是原子的.

  • Short reads: read(fd, buf, n) need not read n bytes. It could read anywhere between 1 and n bytes, and when you call it again to read the remainder, that second read is no longer atomic with respect to the first one.

其他文件类型:POSIX仅保证常规文件和其他一些类型的原子性为read.诸如Linux 可能之类的特定系统具有更强的保证,但我会保持谨慎.

Other file types: POSIX only guarantees atomicity of read for regular files and perhaps a few other types. Specific systems like Linux probably have stronger guarantees, but I would be cautious.

最好使用pread函数(您可以在其中指定要从读取而不必寻找该位置的文件偏移,并且在生成的文件位置保持不变的情况下)或对文件访问进行锁定以避免这种问题.

It may be preferable to use the pread function (where you can specify a file offset to read from without having to seek to that position, and where the resulting file position remains unchanged) or perform locking around your file accesses to avoid such problems.

这篇关于C read()线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆