Читаем Programming with POSIX® Threads полностью

Although mutexes and condition variables provide an ideal solution to most synchronization needs, they cannot meet all needs. One example of this is a need to communicate between a POSIX signal-catching function and a thread waiting for some asynchronous event. In new code, it is best to use sigwait or sigwaitinfo rather than relying on a signal-catching function, and this neatly avoids this problem. However, the use of asynchronous POSIX signal-catching functions is well established and widespread, and most programmers working with threads and existing code will probably encounter this situation.

To awaken a thread from a POSIX signal-catching function, you need a mechanism that's reentrant with respect to POSIX signals (async-signal safe). POSIX provides relatively few of these functions, and none of the Pthreads functions is included. That's primarily because an async-signal safe mutex lock operation would be many times slower than one that isn't async-signal safe. Outside of the kernel, making a function async-signal safe usually requires that the function mask (block) signals while it runs — and that is expensive.

In case you're curious, here is the full list of POSIX 1003.1-1996 functions that are async-signal safe (some of these functions exist only when certain POSIX options are defined, such as _POSIX_ASYNCHRONOUS_IO or _POSIX_TIMERS):

accessgetoverrunsigismember
aio_errorgetgroupssigpending
aio_returngetpgrpsigprocmask
aio_suspendgetpidsigqueue
alarmgetppidsigsuspend
cfgetispeedgetuidsleep
cfgetospeedkillstat
cfsetispeedlinksysconf
cfsetospeedlseektcdrain
chdirmkdirtcflow
chmodmkfifotcflush
chownopentcgetattr
clock_gettimepathconftcgetpgrp
closepausetcsendbreak
creatpipetcsetattr
dup2readtcsetpgrp
duprenametime
execlermdirtimer_getoverrun
execvesem_posttimer_gettime
_exitsetgidtimer_settime
fcntlsetpgidtimes
fdatasyncsetsidumask
forksetuiduname
fstatsigactionunlink
fsyncsigaddsetutime
getegidsigdelsetwait
geteuidsigemptysetwaitpid
getgidsigfillsetwrite

POSIX.1b provides counting semaphores, and most systems that support Pthreads also support POSIX.1b semaphores. You may notice that the sem_post function, which wakes threads waiting on a semaphore, appears in the list of async-signal safe functions. If your system supports POSIX semaphores ( defines the _POSIX_SEMAPHORES option), then Pthreads adds the ability to use semaphores between threads within a process. That means you can post a semaphore, from within a POSIX signal-catching function, to wake a thread in the same process or in another process.

A semaphore is a different kind of synchronization object — it is a little like a mutex, a little like a condition variable. The differences can make semaphores a little harder to use for many common tasks, but they make semaphores substantially easier to use for certain specialized purposes. In particular, semaphores can be posted (unlocked or signaled) from a POSIX signal-catching function.

Semaphores are a general synchronization mechanism. We just have no reason to use them that way.

I am emphasizing the use of semaphores to pass information from a signal-catching function, rather than for general use, for a couple of reasons. One reason is that semaphores are part of a different standard. As I said, most systems that support Pthreads will also support POSIX. lb, but there is no such requirement anywhere in the standard. So you may well find yourself without access to semaphores, and you shouldn't feel dependent on them. {Of course, you may also find yourself with semaphores and without threads — but in that case, you should be reading a different book.)

Another reason for keeping semaphores here with signals is that, although semaphores are a completely general synchronization mechanism, it can be more difficult to solve many problems using semaphores—mutexes and condition variables are simpler. If you've got Pthreads, you only need semaphores to handle this one specialized function — waking a waiting thread from a signal-catching function. Just remember that you can use them for other things when they're convenient and available.

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных