This is accomplished by adding the condition variable attribute clock. You set the clock attribute in a thread attributes object using pthread_condattr_setclock and request the current value by calling pthread_condattr_getclock. The default value is CLOCK_MONOTONIC, on the assumption that most condition waits are intervals.

While this assumption may be incorrect, and it may seem to be an incompatible change from Pthreads (and it is, in a way), this was swept under the rug due to the fact that the timed condition wait function suffered from a problem that POSIX.1j found to be extremely common through the existing body of POSIX standards. 'Time' in general was only very loosely defined. A timed condition wait, for example, does not say precisely what the timeout argument means. Only that 'an error is returned if the absolute time specified by abstime passes (that is, system time equals or exceeds abstime).' The intent is clear — but there are no specific implementation or usage directives. One might reasonably assume that one should acquire the current time using clock_gettime (CLOCK_REALTIME, snow), as suggested in the associated rationale. However, POSIX 'rationale' is little more than historical commentary, and is not part of the formal standard. Furthermore, clock_gettime is a part of the optional _POSIX_TIMERS subset of POSIX.1b, and therefore may not exist on many systems supporting threads.

POSIX.1j is attempting to 'rationalize' all of these loose ends, at least for systems that implement the eventual POSIX.1j standard. Of course, the CLOCK_MONOTONIC feature is under an option of its own, and additionally relies on the _POSIX_TIMERS

option, so it isn't a cure-all. In the absence of these options, there is no clock attribute, and no way to be sure of relative timeout behavior — or even completely portable behavior.

10.2.5 Thread abort

The pthread_abort function is essentially fail-safe cancellation. It is used only when you want to be sure the thread will terminate immediately. The dangerous aspect of pthread_abort is that the thread does not run cleanup handlers or have any other opportunity to clean up after itself. That is, if the target thread has a mutex locked, the thread will terminate with the mutex still locked. Because you cannot unlock the mutex from another thread, the application must be prepared to abandon that mutex entirely. Further, it means that any other threads that might be waiting for the abandoned mutex will continue to wait for the mutex forever unless they are also terminated by calling pthread_abort.

In general, real applications cannot recover from aborting a thread, and you should never, ever, use pthread_abort. However, for a certain class of applications this capability is required. Imagine, for example, a realtime embedded control system that cannot shut down and must run reliably across any transient failure in some algorithm. Should a thread encounter a rare boundary condition bug, and hang, the application must recover.

In such a system, all wait operations use timeouts, because realtime response is critical. Should one thread detect that something hasn't happened in a reasonable time, for example, a navigational thread hasn't received sensor input, it will notify an 'error manager.' If the error manager cannot determine why the thread monitoring the sensor hasn't responded, it will try to recover. It may attempt to cancel the sensor thread to achieve a safe shutdown, but if the sensor thread fails to respond to the cancel in a reasonable time, the application must continue anyway. The error manager would then abort the sensor thread, analyze and correct any data structures it might have corrupted, create and advertise new mutexes if necessary, and create a new sensor thread.

10.3 POSIX 1003.14

POSIX.14 is a different sort of standard, a 'POSIX Standard profile.' Unlike Pthreads and POSIX.1j, POSIX. 14 does not add any new capabilities to the POSIX family. Instead, it attempts to provide some order to the maze of options that faces implementors and users of POSIX.

The POSIX.14 specifies which POSIX optional behavior should be considered 'required' for multiprocessor hardware systems. It also raises some of the minimum values defined for various POSIX limits. The POSIX.14 working group also

devised recommendations for additional POSIX interfaces based on the substantial multiprocessing and threading experience of the members. Many of the interfaces developed by POSIX. L4 have been included in the POSIX.1j draft standard.

Once POSIX.14 becomes a standard, in theory, producers of POSIX implementations will be able to claim conformance to POSIX.14. And those who wish to develop multithreaded applications may find it convenient to look for POSIX. 14 conformance rather than simply Pthreads conformance. (It remains to be seen whether vendors or users will actually do this, since experience with POSIX Standard Profiles is currently slight.)

The POSIX.14 working group also tried to address important issues such as these:

• Providing a way for threaded code to determine the number of active processors.

• Providing a way for threads to be 'bound' onto physical processors.

• Providing a 'processor management' command to control which processors are used by the system.

Although these capabilities are universally available in all multiprocessor systems of which the working group was aware, they were dropped from the standard because of many unresolved issues, including these:

• What good does it do to know how many processors there are, if you cannot tell how many your code may use at any time? Remember, the information can change while you are asking for it. What is really needed is a function asking the question 'Would the current process benefit from creation of another thread?' We don't know how to answer that question, or how to provide enough information on all reasonable architectures that the application can answer it.

• How can we bind a thread to a processor across a wide range of multiprocessor architecture? On a nonuniform memory access system, for example, representing the processors as a uniform array of integer identifiers would be misleading and useless —- binding one thread to processor 0 and another closely cooperative thread to processor 1 might put them across a relatively slow communications port rather than on two processors sharing a bank of memory.

Eventually, some standards organization (possibly POSIX) will need to address these issues and develop portable interfaces. The folks who attempt this feat may find that they need to limit the scope of the standard to a field narrower than 'systems on which people may wish to use threads.'

Bibliography

[Anderson, 1991] Thomas E. Anderson, Brian N. Bershad, Edward D. Lazowska, and Henry M. Levy, 'Scheduler Activations: Effective Kernel Support for the User-Level Management of Parallelism,' Proceedings of the Thirteenth ACM Symposium on Operating Systems Principles, October 1991. Research paper describing the addition of an efficient 'two-level scheduler' mechanism for operating systems. This is where all modern two-level scheduler systems started—everyone's read it, everyone references it, and everyone's been inspired by it.

[Birrell, 1989] Andrew D. Birrell, An Introduction to Programming with Threads, SRC Research Report 35, Digital Systems Research Center, 130 Lytton Ave., Palo Alto, CA 94301, January 1989. Available on Internet from http:// www.research.digital.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×