满足特定条件时才能保证实时响应。本节介绍了这些条件以及一些比较严重的设计错误。
此处介绍的大多数潜在问题都会延长系统的响应时间。其中一个潜在问题可能会冻结工作站。其他更为隐蔽的错误包括优先级倒置和系统过载。
Solaris 实时进程具有以下特征:
本章中介绍的实时操作都是针对单线程进程的,但相关说明同样适用于多线程进程。有关多线程进程的详细信息,请参见《多线程编程指南》。要保证实时调度线程,必须将线程创建为绑定线程。另外,线程的 LWP 必须在 RT 调度类中运行。内存锁定和早期动态绑定对于进程中的所有线程都有效。
如果进程是优先级最高的实时进程,则此进程会在变为可运行的保证分发延迟期间内获取处理器。有关更多信息,请参见分发延迟。只要此进程仍然是优先级最高的可运行进程,它便会继续运行。
实时进程可能会因为其他系统事件而失去对处理器的控制,还可能会因为其他系统事件而无法获取对处理器的控制。这些事件包括:外部事件(如中断)、资源匮乏、等待外部事件(如同步 I/O)以及进程被优先级较高的进程抢占。
实时调度通常不适用于系统初始化和终止服务,例如 open(2) 和 close(2)。
本节所述的问题会在不同程度上延长系统的响应时间。这种延长可能会非常严重,以至导致应用程序错过临界期限。
实时处理还可能削弱运行实时应用程序的系统上处于活动状态的其他应用程序各个方面的操作。由于实时进程具有较高的优先级,因此可能会长时间阻止分时进程运行。这种现象会导致交互式活动(如显示器和键盘响应时间)明显减慢。
SunOS 中的系统响应不提供 I/O 事件的时限。这意味着不应在任何执行时间性强的程序段中包含同步 I/O 调用。即使允许具有较长时限的程序段也不能执行同步 I/O。海量存储 I/O 即是这样一个示例,它会导致在执行读写操作时将系统挂起。
常见的应用程序错误是执行 I/O 以从磁盘获取错误消息文本。应该通过独立进程或独立线程以此方式执行 I/O 操作。此类独立进程或独立线程不应该实时运行。
中断优先级与进程优先级无关。为一组进程设置的优先级不会由这些进程的操作所导致的硬件服务中断继承。结果,高优先级的实时进程控制的设备不一定具有高优先级的中断处理。
分时进程可以使用动态链接的共享库节省大量的内存。此类型的链接通过文件映射的形式实施。动态链接的库例程会导致隐式读取。
实时程序可以在调用该程序时将环境变量 LD_BIND_NOW 设置为非 NULL 值。通过设置此环境值的值,可以使用共享库,同时避免动态绑定。此过程还强制在程序开始执行之前绑定所有动态链接。有关更多信息,请参见《链接程序和库指南》。
分时进程可以通过获取实时进程所需的资源来阻塞实时进程。当较高优先级的进程被较低优先级的进程阻塞时,会发生优先级倒置。术语阻塞描述某个进程必须等待一个或多个进程放弃对资源的控制的情况。如果该阻塞的时间延长,则实时进程可能会错过其期限。
考虑下图中描述的情况,其中高优先级进程需要共享资源。而较低优先级的进程拥有该资源并由中等优先级的进程抢占,从而阻塞了高优先级进程。其中可涉及任意数量的中间进程。必须执行完所有中间进程以及优先级较低的进程的关键部分。这一系列执行操作可能需要任意长时间。
图 12-1 无限制的优先级倒置
《多线程编程指南》中的"互斥锁属性"中介绍了此问题以及处理此问题的方法。
页面在其锁定计数达到 65535 (0xFFFF) 时会永久锁入内存。值 0xFFFF 通过实施定义,并且在将来的发行版本中可能会更改。以此方式锁定的页面无法解除锁定。
失控实时进程可能会导致系统停止。此类失控进程还可能会大幅减慢系统响应,以致系统看起来好像已停止。
注 - 如果在 SPARC 系统上具有失控进程,请按 Stop-A。您可能必须按 Stop-A 多次。如果按 Stop-A 不起作用,请关闭电源,等待片刻,然后重新打开电源。如果在非 SPARC 系统上具有失控进程,请关闭电源,等待片刻,然后重新打开电源。
如果某个高优先级实时进程不放弃对 CPU 的控制,您必须中断无限循环以便重新获取对系统的控制。此类失控进程对于 Ctrl-C 不响应。尝试在高于失控进程优先级的优先级使用 shell 集不起作用。
异步 I/O 操作不总是按照操作在内核中排列的顺序执行。异步操作不一定按照执行操作的顺序返回至调用者。
如果为 aioread(3AIO) 调用的快速序列指定了单个缓冲区,则该缓冲区的状态不确定。缓冲区状态的不确定性从首次调用开始,到将最后结果通知给调用者结束。
单个 aio_result_t 结构仅可以用于一个异步操作。操作可以是读取或写入操作。
SunOS 不提供工具来确保按照物理连续性分配文件。
对于常规文件,始终缓冲 read(2) 和 write(2) 操作。应用程序可以使用 mmap(2) 和 msync(3C) 实现辅助存储和进程内存之间的直接 I/O 传输。