2011-09-07 99 views
0

假设两个进程(或线程)都在缓冲区已满的管道/套接字/终端上调用write,从而阻塞。缓冲区空间变得可用时,是否有保证谁先写入?它是先进先出顺序吗?在全球范围内,还是在给定的优先级别内,并首先按优先级排序?或者它是完全随机的/不确定的?Linux IO优先级 - fifo命令? ...要么?

饥饿的读法呢?第一次拨打电话read是否会在数据可用时获取数据?

我在Linux上特别提出问题,据我所知POSIX对这些问题没有什么可说的,但如果我错了,我也会感兴趣,而且POSIX确实要求特定的行为。

回答

5

在内核中,管道读取器和写入器都使用pipe_wait()函数进行阻塞。该函数使用宏DEFINE_WAIT()来定义一个等待队列,该队列将等待队列的.flags成员设置为零。

他们被叫醒wake_up_interruptible_sync_poll(),其中调用__wake_up_common()。您可以看到,如果.flags成员没有设置WQ_FLAG_EXCLUSIVE位(在这种情况下),那么全部服务员都会被无意中设置为可运行。

然后,调度程序将使用其正常启发式方法来选择要运行的可运行进程。具体而言,具有更高优先级的稍后服务员将首先进入 - 但请注意,如果您有多个可用的处理器核心,则多个服务员可以同时开始运行,并且首先实际接触管道的服务器完全取决于哪一个设法抢先管道锁。

2

简短的回答:

更高优先级的进程可能会得到它第一次,但应用程序不应该让这种行为的假设。

附加信息:

当数据可以用一个管/插座,可以出现争用状态,其中一个看似随机过程可以首先获取锁。在通用中,更高优先级的进程将首先获得锁,但这应该依赖于而不是,因为许多其他因素可能导致此,例如处理器核心和活动线程的数量。

通常,用户级别的应用程序可以假定更高的优先级将确保更频繁的I/O访问,但不应该期望或假定在这些通用性之外定义的一致行为。

+0

这不就是默认调度程序吗?还是他们删除了Kconfig选项? –

+0

你是对的,这是默认的,但还有其他的选择,这真的是要证明这一点;除了泛化之外,用户应用程序不能依赖于特定的调度特性。 – Unsigned