📄 170.htm
字号:
------ <br>
- Instead of the old BSD style gettimeofday()/settimeofday() calls, <br>
POSIX.1b defines clock_gettimer(), clock_settimer() and <br>
clock_getres(). They offer nanosecond resolution instead of <br>
microseconds as with the old BSD calls (at least on Pentiums, a <br>
timer resolution much than a microsecond is available). In <br>
addition, you can query now the actual resolution of the timer <br>
with clock_getres(). <br>
- A new function nanosleep() allows to sleep also for less than a <br>
second (the old sleep() had only second resolution). In addition, <br>
nanosleep won't interfere with SIGALRM and in case of EINTR, it <br>
returns the time left, so you can easily continue in a while loop. <br>
- POSIX.1b defines also itimers, however instead of what the <br>
existing BSD itimers provide, you now can deal with several timers <br>
(at least 32 per process) and you have again theoretically up to <br>
one nanosecond resolution. The old itimer functions can still <br>
easily be implemented in libc for compatibility reasons using new <br>
POSIX-style itimer system calls. <br>
Implementation status: The POSIX clock and itimers system calls have <br>
not not yet been implemented, although much of the functionality is <br>
already available in the form of the BSD timers and adding them should <br>
be quite easy. Queued signals have to be implemented first for <br>
itimers. Nanosleep() is already available in Linux, but at the moment <br>
it supports only 10 ms resolution and it can optionally perform short <br>
microsecond precision busy waits of up to 2 ms length. <br>
Scheduling <br>
---------- <br>
Linux 1.2 has so far been optimized a lot as a time sharing system, <br>
where several people run application programs like editors, compilers, <br>
debuggers, X window servers, networking daemons, etc. and do word <br>
processing, software development, etc. <br>
However there are a lot of applications for which Linux is currently <br>
unusable and for which even die-hard Linux enthusiasts have to keep a <br>
stand-alone DOS version on their disk. For >90% of these applications, <br>
the fact that Linux is incapable of guaranteeing the response time of <br>
an application is the major problem. Software for controlling e.g. an <br>
EPROM programmer, a robot arm, or an astronomical CCD camera is not <br>
realizable under a classic Unix if there is no dedicated real-time <br>
controller present in the controlled device. A lot of commercially <br>
available hardware has been designed with the real-time "capability" <br>
of DOS in mind and has no own microcontroller for time-critical <br>
actions. <br>
A real-world example: I have myself spent a long frustrating time of <br>
trying to implement an interface to a pay-TV decoder for Linux (which <br>
emulates a chip card and allows you to watch pay-TV for free :-). In <br>
this application, you have to wait for an incoming byte on the serial <br>
port, then you have to wait for around 0.7 to 2 ms (never shorter, <br>
never longer, otherwise the TV decoder gets a timeout and stops!) <br>
before returning an answer byte. It is virtually impossible to <br>
implement a user process for this task under Linux 1.2, while it is <br>
trivial to do this under DOS. I am looking forward to the day when <br>
Linux provides enough real-time support for this application so that I <br>
can finally remove MS-DOS from my harddisk. <br>
For these and similar real-time applications, POSIX.1b specifies three <br>
different schedulers, each with static priorities: <br>
SCHED_FIFO A preemptive, priority based scheduler. Each process <br>
managed under this scheduling priority possesses the <br>
CPU as long as (a) it does not block itself and (b) <br>
there comes no interrupt which puts another process <br>
into a higher priority wait queue. There exists a FIFO <br>
queue for each priority level and every process which <br>
gets runnable again is inserted into the queue behind <br>
all other processes. This is the most popular <br>
scheduler used in typical real-time operating <br>
systems. Function sched_yield() allows the process to <br>
go to the end of the FIFO queue without blocking. <br>
SCHED_RR A preemptive, priority based round robin scheduling <br>
strategy with quanta. It is a very similar to <br>
SCHED_FIFO, however each process has a time quantum and <br>
the process becomes preempted and is inserted at the <br>
end of the FIFO for the same priority level if it <br>
runs longer than the time quantum and other processes <br>
of the same priority level are waiting in the queue. <br>
Processes of lower priorities will like in SCHED_FIFO <br>
never get the CPU as long as a higher level process <br>
is in a ready queue and if a higher priority process <br>
becomes ready to run, it also gets the CPU immediately. <br>
SCHED_OTHER This is any implementation defined scheduler. Under <br>
Linux it is the classic time-sharing scheduler with <br>
"nice" values, etc. Under Linux, all SCHED_OTHER <br>
processes share the common static priority value 0. <br>
For security reasons, only root processes should under Linux be <br>
allowed to get any static priority higher than the one for <br>
SCHED_OTHER, because if these real-time scheduling mechanisms are <br>
abused, the whole system can be blocked. <br>
If one is developing a real-time application, it is a very good idea <br>
to have a shell with a higher static priority somewhere open in order <br>
to be able to kill the tested application in case something goes <br>
wrong. You should be aware, that if you use X11, not only the shell, <br>
but also the X server, the window manager and xterm will require a <br>
higher static priority in order to stop processes blocking the rest of <br>
the system. Therefore, testing real-time software will usually better <br>
be done on the console. <br>
With this POSIX.1b functionality, it is possible to run real-time <br>
software under Linux by giving it root permissions and assigning it a <br>
SCHED_FIFO strategy and a higher static priority than all other <br>
classic SCHED_OTHER Linux processes. In addition, typical real-time <br>
application lock their pages with mlockall() into the memory in order <br>
to avoid being swapped out. This guarantees that the real-time <br>
application can react as soon as possible on any interrupts and that <br>
the response time will not be influenced by the complicated normal <br>
Linux time-sharing priority mechanisms or by paging. However, please <br>
read also the chapter on interrupt dispatch latency below! <br>
The new functions are here: <br>
sched_setparam(), sched_getparam(), sched_setscheduler(), <br>
sched_getscheduler(), sched_yield(), sched_get_priority_max(), <br>
sched_get_priority_min(), sched_rr_get_interval(). <br>
Implementation status: The sched_*() system calls are now available <br>
since Linux 1.3.55 (Markus Kuhn <mskuhn@cip.informatik.uni-erlangen.de>). <br>
Although much testing, performance evaluation, and optimization with <br>
the real-time scheduler is necessary (especially with regard to "fast <br>
interrupt handling, see below), you can already use the sched_*() <br>
calls in order to get the processor exclusively. There are also libc <br>
and manual pages available. Some earlier work on this was done by <br>
David F. Carlson <carlson@dot4.com> in his POSIX.4_scheduler patch <br>
against Linux 1.2 (still available on sunsite). <br>
Asynchronous I/O (aio) <br>
---------------------- <br>
POSIX.1b defines a number of functions which allow to send a long list <br>
of read/write requests at various seek positions in various files to <br>
the kernel with one single lio_listio() system call. While the process <br>
continues to execute the next instructions, the kernel will <br>
asynchronously read or write the requested pages and will send signals <br>
when the task has been completed (if this is desired). <br>
This is very nice for a database which knows that it will require a <br>
lot of different blocks scattered on a file. It will simply pass a <br>
list of the blocks to the kernel, and the kernel can optimize the disk <br>
head movement before sending the requests to the device. In addition <br>
this minimizes the number of system calls and allows the database to <br>
do something else in the meantime (e.g. waiting for the client process <br>
sending an abort instruction in which case the database server can <br>
cancel the async i/o requests with aio_cancel()). <br>
Another important application of aio are multimedia systems like MPEG <br>
or sound file players and recorders. These programs want to preload <br>
the next few seconds of the data stream from harddisk into locked <br>
memory, but also want to continue showing the video on the screen at <br>
the same time without any interruptions caused by synchronous I/O. The <br>
POSIX.1b async I/O calls provide a nice way for such anticipatory <br>
loading. <br>
POSIX.1b also defines priorities for asynchronous I/O, i.e. there is a <br>
way to tell the kernel that the read request for the MPEG player is <br>
more important than the read request of gcc. On a future real-time <br>
Linux, you don't want to see any image distortions while watching MPEG <br>
video and compiling a kernel at the same time if you gave the MPEG <br>
player a higher static priority. <br>
New functions in this area are: <br>
aio_read(), aio_write(), lio_listio(), aio_suspend(), aio_cancel(), <br>
aio_error(), aio_return(), aio_fsync(). <br>
Implementation status: Not yet implemented. The aio functions are <br>
probably best implemented in libc using kernel threads and the normal <br>
synchronous I/O system calls. There has recently been some progress on <br>
implementing kernel threads in Linux 1.3 using the clone() system <br>
call. Adding priority I/O to Linux might be a more complicated job, <br>
because many device drivers would have to be extended by priority wait <br>
queues. <br>
queues. <br>
Implemented options <br>
------------------- <br>
As POSIX.1b conformance does not require the implementation of all <br>
these functions, macros have been specified for <unistd.h> that <br>
indicate to application software which of the POSIX.1b functionality <br>
is available on this system. This way, portable software can be <br>
written that uses real-time features only when they are available. <br>
Under the latest Linux kernel and libc development versions, the <br>
following POSIX.1b macros have been defined and indicate implemented <br>
functions: <br>
_POSIX_FSYNC <br>
_POSIX_MAPPED_FILES <br>
_POSIX_MEMLOCK <br>
_POSIX_MEMLOCK_RANGE <br>
_POSIX_MEMORY_PROTECTION <br>
_POSIX_PRIORITY_SCHEDULING <br>
The POSIX.1b options indicated by the following macros have not yet <br>
been implemented under Linux: <br>
_POSIX_ASYNCHRONOUS_IO <br>
_POSIX_MESSAGE_PASSING <br>
_POSIX_PRIORITIZED_IO <br>
_POSIX_REALTIME_SIGNALS <br>
_POSIX_SEMAPHORES <br>
_POSIX_SHARED_MEMORY_OBJECTS <br>
_POSIX_SYNCHRONIZED_IO <br>
_POSIX_TIMERS <br>
General real-time problems <br>
-------------------------- <br>
Apart from implementing new POSIX.1b system calls, there are a number <br>
of other problems with the current Linux kernel that have to be solved <br>
in order to improve real-time performance. <br>
Problem 1: Interrupt dispatch latency <br>
A blocked process waiting for the end of some I/O request becomes <br>
runnable again when the CPU receives an interrupt from the I/O device <br>
that processed the request. The time that passes between the interrupt <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -