从两个线程同时读取文件描述符

时间:2011-02-20 14:52:23

标签: multithreading posix file-descriptor

  1. 我的问题:在Linux(以及FreeBsd中,通常在UNIX中)是否可以同时从两个线程读取单个文件描述符?

  2. 我做了一些搜索但没有发现任何东西,虽然很多人问同时读/写插座fd的问题(意思是在其他线程写入时读取,而不是在其他读取时读取) )。我也阅读了一些手册页,对我的问题没有明确的答案。

  3. 为什么我问它。我试图实现简单的程序来计算stdin中的行,比如wc -l。我实际上正在测试我的自制C ++ io引擎的开销,并发现wc快1.7倍。我减少了一些C ++并接近wc速度但没有达到它。然后我尝试了输入缓冲区大小,对其进行了优化,但是wc显然要快一点。最后我创建了两个并行读取相同STDIN_FILENO的线程,这最后比wc快!但是行计数变得不正确......所以我认为一些垃圾来自于意外的读取。内核不关心什么过程读取?

  4. 编辑:我做了一些研究,发现只是通过系统调用直接调用read不会改变任何东西。内核代码似乎做了一些同步处理,但我不太了解(read_write.c)

3 个答案:

答案 0 :(得分:3)

这是未定义的行为,posix说:

read()函数应尝试从与open文件描述符相关联的文件中读取nbyte字节,fildes到buf指向的缓冲区。未指定同一管道,FIFO或终端设备上的多个并发读取的行为。

答案 1 :(得分:1)

当与描述符(fd)一起使用时,read()和write()依赖于fd的内部状态来知道读和写将发生的“当前偏移”。因此,它们不是线程安全的。

为了允许多个线程同时使用单个描述符,提供了pread()和pwrite()。使用这些接口,指定描述符和所需的偏移量,因此不使用描述符中的“当前偏移量”。

答案 2 :(得分:0)

关于同时访问单个文件描述符(即从多个线程甚至进程),我将引用POSIX.1-2008 (IEEE Std 1003.1-2008), Subsection 2.9.7 Thread Interactions with Regular File Operations

  

2.9.7与常规文件操作的线程交互

     

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

     

[…] read()[…]

     

如果两个线程各自调用这些函数之一,则每个调用应要么看到另一个调用的所有指定作用,要么都不看到。 […]

乍一看,这看起来还不错。但是,希望它们在对常规文件或符号链接进行操作时不会错过限制。