【问题标题】:Is this a possible race with select/poll/epoll/kqueue?这是否可能与 select/poll/epoll/kqueue 竞争?
【发布时间】:2017-08-16 13:34:27
【问题描述】:

我正在研究select()/poll()/epoll()kqueue() 的语义,以决定如何在用户空间中为我的operating system 模拟它们。

请注意,我只关心文件读/写/异常多路复用,而不关心信号、子进程状态、计时器等...

我已经阅读了一些关于他们的资源、他们的比较、他们的优势和他们的问题,但我找不到任何关于某个特定种族的信息,据我所知,它会影响所有人。

假设您有一个多路复用进程在 select(或任何其他组)中等待文件可读。在select 返回之后,但在进程可以read 那个特定fd 之前,另一个进程共享同一个描述符read 文件。据我所知,多路复用过程中的read 会阻塞(直到有更多数据可用)。

我知道这是应用程序中的一个错误(多路复用描述符不应该对同时使用它们的任何其他进程可用)但我仍然想知道这是否是一种可能的情况以及各种操作系统是否有任何作用防止这样的比赛。
实际上,尽管可能很复杂,但它们可以阻止竞争,例如阻止 select 在除多路复用进程之外的所有进程上“返回为可读”的特定描述符的读取,直到该进程耗尽事件(又名read fd)。显然对于更奇特的事件,这可能是不可能的,但我在这里只考虑文件读/写。

注意:这个问题是关于种族的,而不是每个系统调用的细节,所以请不要试图解释差异/优势等,如果它们与这个特定的无关种族。

编辑为了澄清,我正在考虑实际上可以在读/写时阻塞的文件,因为正如 Linux 上的 select(2) 手册所解释的那样

如果一个文件描述符可以执行 相应的 I/O 操作(例如,无阻塞的 read(2),或 足够小的写入(2))。

【问题讨论】:

  • 进程并不真正共享描述符,即使它们是相关的(例如分叉的)并且具有相同的编号并引用相同的文件。它仍然是两个不同的描述符,有自己的缓冲。另一个进程可能在轮询和文件读取或写入之间仍然删除或修改文件,导致其他问题。
  • 嗯,AFAIK,这对于所有的 Unix 衍生产品来说都不是真的(至少 Plan 9 不是这样...... :-D)。我仍然不确定这是否能回答我对 Linux/BSD 的问题:既然你没有告诉内核你要读多少,那么缓冲区如何相关?
  • 缓冲区并不真正相关,但重要的是它是两个不同且不同的文件描述符。从同一个文件读取两个进程(无论一个是从另一个分叉出来的)根本不是问题。如果一个进程都只从文件中读取,则一个进程不会阻塞另一个进程。
  • 除非文件描述符是非阻塞的,否则无论 poll&co 返回什么,您都可以阻塞读取。此外, poll&co 对普通文件毫无意义,并且将(或至少应该)返回该文件始终可读。答案是:没有人做任何事情来阻止这场比赛,因为这是一场毫无意义的比赛。在实际场景中,当一个线程处于轮询状态而另一个线程从 fd 中读取时,轮询线程最坏的情况是会醒来,从 fd 中读取,因为 fd 是非阻塞的,所以会出错并重新进入轮询状态。
  • @Art 我试图澄清一下,我显然在考虑可以在读/写时阻塞的文件描述符。

标签: c unix file-io concurrency


【解决方案1】:

读取文件时,一旦到达EOF,read会自动返回。这个问题是否与SOCKET读取有关?

【讨论】:

    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 2010-09-09
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多