|
531 | 531 | \end{slide} |
532 | 532 |
|
533 | 533 | \begin{itemize} |
534 | | -\item \label{THREAD_SPECIFIC_DATA} Common global variables and dynamically |
| 534 | +\item \label{THREAD_SPECIFIC_DATA} Global variables and dynamically |
535 | 535 | allocated data is common to all threads. Thread specific data provides a way to |
536 | 536 | create a global variable per thread. Note the difference between that and a |
537 | | -local variable in the thread function. The local variable is not visible in |
538 | | -other functions called from the thread function. Thread specific data is a very |
539 | | -useful feature. Imagine you have existing multithreading code using a global |
540 | | -storage place which suffers from lots of contention. You can easily create a |
541 | | -thread specific data to create a storage place per thread with minimal changes |
542 | | -to the original code. |
| 537 | +local variable in the thread function -- as you know, in C, the local variable |
| 538 | +is not visible in other functions called from the thread function. Thread |
| 539 | +specific data is a very useful feature. Imagine you have existing |
| 540 | +multithreading code using a global storage place which suffers from heavy |
| 541 | +contention. You can easily create a thread specific data to create a storage |
| 542 | +place per thread with minimal changes to the original code. |
543 | 543 | \item When you create a key, \texttt{NULL} is associated with it. If you do not |
544 | 544 | need the destructor function, use \texttt{NULL}. |
545 | 545 | \item Destructors are called in unspecified order on all keys with a value |
|
622 | 622 | \item Examples: \example{pthreads/fork.c}, |
623 | 623 | \example{pthreads/fork-not-in-main.c}, and also \example{pthreads/forkall.c} |
624 | 624 | \item \label{ATFORK} You can use \funnm{pthread\_atfork}() to set handlers that |
625 | | -are executed before \funnm{fork}() is called in the parent, and then after |
626 | | -\funnm{fork}() is called both in the parent and its child. Such handlers are |
627 | | -very useful when \funnm{fork}() is used not only as a wrapper around |
628 | | -\funnm{exec}(). |
629 | | -After \funnm{fork}(), all variables in the child are in the state as in the |
630 | | -parent, so if a thread not present to the child held a mutex in the parent |
631 | | -(see page \pageref{MUTEXES}), the mutex stays |
632 | | -locked in the child, and trying to lock in the child will lead to a deadlock. |
633 | | -However, if the parent locks all the mutexes in the \emph{\texttt{pre-fork}} |
634 | | -handler and then unlocks them in the \emph{\texttt{post-fork}} handler (both |
635 | | -for the parent and the child), you will avoid such deadlocks. When locking |
636 | | -mutexes in the \emph{\texttt{pre-fork}} handler, other threads are still running |
637 | | -so the mutexes held by them can be released (usually each thread exits a |
638 | | -critical section in a short time in well written code). |
639 | | -Example: \example{pthreads/atfork.c}. For more on this topic, see [Butenhof]. |
| 625 | +are executed before \funnm{fork}() is called in the parent process, and then after |
| 626 | +\funnm{fork}() is called both in the parent and its child. The handlers are |
| 627 | +executed in the context of the thread that calls the \funnm{fork}(). Such |
| 628 | +handlers are very useful when \funnm{fork}() is used not only as a wrapper |
| 629 | +around \funnm{exec}(). After \funnm{fork}(), all variables in the child are in |
| 630 | +the state as in the parent, so if a thread not present to the child held a mutex |
| 631 | +in the parent (see page \pageref{MUTEXES}), the mutex stays locked in the child, |
| 632 | +and trying to lock in the child will lead to a deadlock. However, if the parent |
| 633 | +locks all the mutexes in the \emph{\texttt{pre-fork}} handler and then unlocks |
| 634 | +them in the \emph{\texttt{post-fork}} handler (both for the parent and the |
| 635 | +child), you will avoid such deadlocks. That is because when locking mutexes in |
| 636 | +the \emph{\texttt{pre-fork}} handler, other threads are still running so the |
| 637 | +mutexes held by them should be released eventually (usually each thread exits a |
| 638 | +critical section in a short time in well written code). Example: |
| 639 | +\example{pthreads/atfork.c}. For more on this topic, see [Butenhof]. |
640 | 640 | \item See page \pageref{MUTEXES} on why mutexes locked in other threads on |
641 | 641 | \funnm{fork}() stay locked forever. |
642 | 642 | \end{itemize} |
|
675 | 675 | will exit, not just one thread. |
676 | 676 | \item New thread will inherit signal mask from the creator thread. |
677 | 677 | \item Similarly to the use of \texttt{sigwait} with processes (page |
678 | | -\pageref{SIGWAIT}) -- block given signals in all threads, including the |
679 | | -thread, that will be processing the signals using \texttt{sigwait}. |
| 678 | +\pageref{SIGWAIT}) -- just block given signals in all threads, including the |
| 679 | +thread processing the signals using \texttt{sigwait}. |
680 | 680 | \emsl{This way of signal handling in threaded environment is usually the only |
681 | | -recommended.} Also, it is easy to implement. From previous note, it is sufficient |
682 | | -to mask the signals only once, in the main thread (before creating any new |
683 | | -threads), because the mask will be inherited with each \texttt{pthread\_create} |
684 | | -call. |
| 681 | +recommended.} And it is easy to implement as well. From a previous note, it is |
| 682 | +sufficient to mask the signals only once, in the main thread (before creating |
| 683 | +any new threads), because the mask will be inherited with each |
| 684 | +\texttt{pthread\_create} call. |
685 | 685 | \item Do not use \texttt{sigprocmask} (page \pageref{SIGPROCMASK}) in threaded |
686 | 686 | environment, because the behavior of this call is not specified by the standard |
687 | 687 | in such environment. It may work, or not. |
|
706 | 706 | itself as ``Gentoo Base System release 1.12.13'', is the \texttt{SIGSEGV} signal |
707 | 707 | delivered and the process killed even though it is masked. |
708 | 708 | There used to be a system that did not deliver the signal when masked |
709 | | --- FreeBSD 6.0. It should be possible to always handle synchronous signals |
710 | | -(before \texttt{exit}), see page \pageref{SPECIALSIGNALS}, which also |
711 | | -contains example. |
| 709 | +-- FreeBSD 6.0. It should be possible to handle synchronous signals |
| 710 | +if you terminate the process in the handler itself (e.g. after printing a user |
| 711 | +friendly error message), see page \pageref{SPECIALSIGNALS}, which also contains |
| 712 | +an example. |
712 | 713 |
|
713 | 714 | \end{itemize} |
714 | 715 |
|
|
0 commit comments