【发布时间】:2021-09-10 22:31:59
【问题描述】:
我的问题:在 Linux(以及 FreeBsd 中,通常在 UNIX 中)是否可以/合法地同时从两个线程读取单个文件描述符?
我做了一些搜索但一无所获,尽管很多人同时询问有关从/向套接字 fd 读取/写入的问题(意思是在其他线程正在写入时读取,在其他线程正在读取时不读取)。我也阅读了一些手册页,但对我的问题没有明确的答案。
我为什么要问它。我试图实现一个简单的程序来计算标准输入中的行数,比如 wc -l。我实际上是在测试我自制的 C++ io 引擎的开销,发现 wc 快了 1.7 倍。我削减了一些 C++ 并接近 wc 速度但没有达到它。然后我尝试了输入缓冲区的大小,对其进行了优化,但 wc 显然还是快了一点。最后我创建了 2 个并行读取相同 STDIN_FILENO 的线程,这终于比 wc 快了!但是行数变得不正确......所以我想一些垃圾来自意外的读取。内核不关心读取什么进程吗?
编辑:我做了一些研究,发现直接通过系统调用调用 read 并没有改变任何东西。内核代码似乎做了一些同步处理,但我不太了解(read_write.c)
【问题讨论】:
-
顺便说一句:并行读取可能会让你变慢而不是更快。如果您有 I/O 瓶颈,那么您所做的就是创建锁争用。你可以专注于你的缓冲策略。
-
但是我没有锁定,我只是读了,内核应该在内部锁定。关于缓冲:我尝试改变缓冲区大小并提出了一些最佳方案。它仍然比 wc 慢。我现在有一个理论,我需要非阻塞读取来提高性能。
-
非阻塞读取也无济于事。嗯..
-
非阻塞读取 + 8 页缓冲区大小 + std::count 最终击败 wc -l。没关系,这不完全是我的问题。
-
2 线程正确锁定比最好的单线程版本快 20%。因为我只有 2 个内核,所以无法测试更多线程。
标签: multithreading posix file-descriptor