home *** CD-ROM | disk | FTP | other *** search
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- NNNNAAAAMMMMEEEE
- pthreads - introduction to POSIX thread characteristics
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- This man page is intended as an overview of the POSIX thread model as
- implemented in IRIX; it is not an introduction to thread programming or a
- detailed description of the IRIX implementation.
-
- Thread programming is motivated by two concerns:
-
- AAAApppppppplllliiiiccccaaaattttiiiioooonnnn PPPPeeeerrrrffffoooorrrrmmmmaaaannnncccceeee
- +o On a multiprocessor multiple threads may run at the same time.
- +o Operations that cause the caller to wait do not prevent other
- threads (in the same process) from making progress.
-
- PPPPrrrrooooggggrrrraaaammmmmmmmiiiinnnngggg MMMMooooddddeeeellll
- +o Complex applications can be structured more elegantly by
- partitioning with threads.
- +o Threads share many resources implicitly which can simplify co-
- operative algorithms.
-
- In the past a UNIX process has been thought of as having a single thread.
- The POSIX thread programming model (known as _p_t_h_r_e_a_d_s) introduces the
- concept of multiple threads within a single process. A POSIX thread is
- an executable entity that belongs to a process. It contains sufficient
- state to enable it to run on a processor independently of its fellows.
- In most other respects threads share state with their host process. The
- vast majority of interfaces and features work the same way in a multi-
- threaded process as an unthreaded one.
-
- The POSIX threads API provides a set of interfaces and semantics for
- creating and controlling threads. Because the interfaces are defined by
- the ISO standards organisation an application using them may enjoy the
- benefits of parallel programming without sacrificing portability.
-
- AAAApppppppplllliiiiccccaaaattttiiiioooonnnnssss
- To create a pthread process an application must be linked with the
- pthread run-time library. It is also recommended that the thread safe
- options be enabled at compile time using the feature test macro,
- ____PPPPOOOOSSSSIIIIXXXX____CCCC____SSSSOOOOUUUURRRRCCCCEEEE.
-
- cc -D_POSIX_C_SOURCE=199506L app.c -llib0 -llib1 ... -lpthread
-
- See _i_n_t_r_o(3), section 3P for further details.
-
- CCCCoooommmmppppoooonnnneeeennnnttttssss
- POSIX threads introduces a number of thread components.
-
- AAAAttttttttrrrriiiibbbbuuuutttteeee
- An attribute is a characteristic of something that defines its
- behaviour. Most of the objects introduced by pthreads have
- characteristics which are set when it is created; indeed some
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- characteristics may only be set at that time. A set of
- characteristics may be specified in an attribute object which is
- passed to the creation interface. An analogy is a mould or template
- that is used to shape some artifact. Every attribute has a default
- value and the attribute object itself is optional.
-
- TTTThhhhrrrreeeeaaaadddd
- A thread executes code. It is created using _p_t_h_r_e_a_d__c_r_e_a_t_e() and
- either inherits characteristics from its creator or has them
- specified via creation attributes. The _p_t_h_r_e_a_d__a_t_t_r_* interfaces
- may be used to create a thread attributes object.
- Many features of the process are shared by its threads, including
- process and user ids (PID, UID), file descriptors, memory (including
- text and data) and signal handlers.
- Each thread has a unique identity which is used by a number of
- pthread interfaces. Thread ids may be compared using
- _p_t_h_r_e_a_d__e_q_u_a_l().
- Threads terminate with an exit status [see _p_t_h_r_e_a_d__e_x_i_t()]. By
- default the thread identity and exit status persist after the thread
- has terminated until the status is retrieved using _p_t_h_r_e_a_d__j_o_i_n().
- An application should either retrieve this status or arrange for it
- to be automatically discarded on thread termination using
- _p_t_h_r_e_a_d__d_e_t_a_c_h() or setting the detach thread attribute.
-
- MMMMuuuutttteeeexxxx LLLLoooocccckkkk
- A mutex lock facilitates exclusive access by a thread to a resource.
- Only one thread may own a mutex at a time and is thus guaranteed
- exclusive access.
- Mutex interfaces are described on the _p_t_h_r_e_a_d__m_u_t_e_x_* man pages.
- The _p_t_h_r_e_a_d__m_u_t_e_x_a_t_t_r_* interfaces may be used to create a mutex
- attributes object. Attributes include error checking, recursion and
- owner priority. Mutexes are intended to be lightweight and only
- owned for brief periods of time.
-
- CCCCoooonnnnddddiiiittttiiiioooonnnn VVVVaaaarrrriiiiaaaabbbblllleeee
- A condition variable synchronises threads with an event of interest.
- Condition variables allow a thread to wait for an event and be woken
- up when the event occurs; the nature of the event is determined by
- the application.
- Condition variable interfaces are described on the _p_t_h_r_e_a_d__c_o_n_d_*
- man pages. The _p_t_h_r_e_a_d__c_o_n_d_a_t_t_r_* interfaces may be used to create
- a condition variable attributes object.
-
- RRRReeeeaaaadddd----WWWWrrrriiiitttteeee LLLLoooocccckkkk
- A read-write lock facilitates shared access for read and exclusive
- access for write by threads to a resource. They are used in
- conjunction with resources which are frequently read but
- infrequently changed (written).
- Read-write lock interfaces are described on the _p_t_h_r_e_a_d__r_w_l_o_c_k_* man
- pages. The _p_t_h_r_e_a_d__r_w_l_o_c_k_a_t_t_r_* interfaces may be used to create a
- read-write lock attributes object.
-
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- SSSSeeeemmmmaaaapppphhhhoooorrrreeee
- A semaphore synchronises threads with a counter. Semaphores are not
- part of pthreads per se and do not have an associated attributes
- object. However anonymous semaphores provide a _p_s_h_a_r_e_d flag (for
- semaphores which are private to the process) which allows pthreads
- to optimise access [see _s_e_m__i_n_i_t(3C)]. Semaphore interfaces are
- described on the _s_e_m_* man pages.
-
- SSSSeeeemmmmaaaannnnttttiiiiccccssss
- POSIX threads introduces the following special semantics.
-
- CCCCaaaannnncccceeeellllllllaaaattttiiiioooonnnn
- A cancellation request is a request for a thread to terminate. Each
- thread specifies whether and when to act on cancellation requests
- using its cancelability state and type. A request is made with
- _p_t_h_r_e_a_d__c_a_n_c_e_l() and the state and type are set with
- _p_t_h_r_e_a_d__s_e_t_c_a_n_c_e_l_s_t_a_t_e() and _p_t_h_r_e_a_d__s_e_t_c_a_n_c_e_l_t_y_p_e(). Termination
- handlers may be established to execute code when a thread terminates
- for some reason including acting on a cancellation request.
-
- SSSSiiiiggggnnnnaaaallllssss
- In the pthread signal model all threads share the signal disposition
- [see _s_i_g_a_c_t_i_o_n(2)] but each thread has its own signal mask of
- blocked signals. Signals may be sent to individual threads using
- the _p_t_h_r_e_a_d__k_i_l_l() interface. Each thread may change its own mask
- using _p_t_h_r_e_a_d__s_i_g_m_a_s_k(). In IRIX, _s_i_g_p_r_o_c_m_a_s_k(2) is equivalent to
- _p_t_h_r_e_a_d__s_i_g_m_a_s_k() but a portable pthread application should only use
- the latter.
- A signal is delivered to at most one thread; it is not broadcast to
- all threads.
-
- +o When a signal is directed at a process the first eligible thread
- is chosen to receive it. An eligible thread is one that does
- not have the signal blocked in its signal mask or is waiting in
- _s_i_g_w_a_i_t(3). If there are no eligible threads then the signal
- remains pending on the process until a thread becomes eligible.
- This is called asynchronous signal delivery; _k_i_l_l(2) causes this
- type of delivery.
-
- +o When a signal is directed at a thread then that thread will
- receive it. If the signal is blocked then it will remain
- pending on the target thread; it will not be delivered to a
- different thread. This is called synchronous signal delivery;
- exceptions and program faults cause this type of delivery.
-
- +o If the action of the signal is to stop, continue or terminate
- the recipient then it will act on the process as a whole. It is
- not possible to stop, continue or terminate a single thread with
- a signal.
-
-
-
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- NNNNoooottttiiiiffffiiiiccccaaaattttiiiioooonnnnssss
- An extension to signal handling for threads is the addition of
- SSSSIIIIGGGGEEEEVVVV____TTTTHHHHRRRREEEEAAAADDDD which creates a thread instead of sending a signal as a
- means of handling the occurrence of some event [see _m_q__n_o_t_i_f_y(3C),
- _a_i_o__r_e_a_d(3) and _t_i_m_e_r__c_r_e_a_t_e(3C)]. Creation of the thread takes
- place when the event occurs so care should be taken to avoid any
- errors or else the notification may be lost.
-
- SSSScccchhhheeeedddduuuulllliiiinnnngggg
- When a processor executes instructions on behalf of a user it does
- so according to a set of scheduling attributes which are part of a
- kernel _e_x_e_c_u_t_i_o_n _v_e_h_i_c_l_e. Every thread that executes on a processor
- or waits in the kernel needs such a vehicle.
-
- POSIX threads makes a distinction between system scope (kernel)
- scheduling and process scope (run-time) scheduling. The SGI
- implementation adds an additional scheduling scope, bound scope.
- These bound scope threads are scheduled exactly the same as POSIX
- process scope threads. For the rest of this man page, the
- discussion of process scope scheduling is applicable for bound scope
- threads. In both scopes the individual thread scheduling policy and
- priority values are set using the interfaces
- _p_t_h_r_e_a_d__a_t_t_r__s_e_t_s_c_h_e_d_p_o_l_i_c_y(), _p_t_h_r_e_a_d__a_t_t_r__s_e_t_s_c_h_e_d_p_a_r_a_m(), and
- _p_t_h_r_e_a_d__s_e_t_s_c_h_e_d_p_a_r_a_m().
-
- Scope is defined when a thread is created using
- _p_t_h_r_e_a_d__a_t_t_r__s_e_t_s_c_o_p_e():
-
- ssssyyyysssstttteeeemmmm ssssccccooooppppeeee threads are scheduled by the kernel; the scheduling
- attributes of the thread and the kernel execution vehicle are the
- same. The kernel includes all system scope threads in its
- scheduling decisions. These threads run at realtime policy and
- priority and may only be created by privileged users.
-
- pppprrrroooocccceeeessssssss ssssccccooooppppeeee threads are scheduled by the pthread run-time; the
- scheduling attributes of the thread and the kernel execution vehicle
- may be different. The run-time makes scheduling decisions based
- only on the process scope threads in the host process.
-
- An advantage of system scope is that a thread can get high
- performance and deterministic response. A disadvantage is that
- kernel resources must be allocated to each thread.
-
- In contrast, process scope threads only require kernel state when
- they are executing on a processor or waiting in the kernel. The
- run-time scheduler multiplexes process scope threads onto a smaller
- number of kernel execution vehicles. This can produce faster
- scheduling because no kernel state is involved.
-
- The number of execution vehicles used for process scope threads
- depends on application behaviour and system configuration. By
- default, the run-time adjusts this number dynamically but the
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- _p_t_h_r_e_a_d__s_e_t_c_o_n_c_u_r_r_e_n_c_y() interface gives a strong hint as to the
- desired value.
-
- The execution vehicles used for process scope threads share a set of
- kernel scheduling attributes which can be changed using the
- _s_c_h_e_d__s_e_t_s_c_h_e_d_u_l_e_r() and _s_c_h_e_d__s_e_t_p_a_r_a_m() interfaces. These
- interfaces do not affect system scope thread scheduling. As with
- system scope threads changing these scheduling attributes is a
- privileged operation.
-
- LLLLoooowwww----oooovvvveeeerrrrhhhheeeeaaaadddd LLLLoooocccckkkkiiiinnnngggg
- In order to protect updates to internal pthread data structures, a
- low-overhead locking mechanism is required. This locking interface
- is not user-callable and is contained entirely within the pthread
- library. When pthreads are present, this locking mechanism is also
- used to ensure that some routines in libc can be safely called from
- multiple threads. Some examples of this are the _s_t_d_i_o(3S) routines
- and the _m_a_l_l_o_c(3C) routines.
-
- By default, these locks spin/sleep for pppprrrroooocccceeeessssssss ssssccccooooppppeeee and bbbboooouuuunnnndddd ssssccccooooppppeeee
- threads on multiprocessor systems, and immediately block for ssssyyyysssstttteeeemmmm
- ssssccccooooppppeeee threads and on single processor systems. In the spin/sleep
- lock path, the lock will be tried 1000 times, and then _n_a_n_o_s_l_e_e_p(2)
- will be called. This process will be repeated until the lock can be
- obtained.
-
- This process can be tuned for an individual application with the
- PPPPTTTT____SSSSPPPPIIIINNNNSSSS environment variable. This determines how many times the
- lock is tried before sleeping. This environment variable is checked
- once at program startup time. Different spin values may be used to
- improve application throughput; however, higher values will probably
- increase user time while lower values will probably increase system
- time. In general, applications with more pthreads than processors
- will probably benefit from setting PPPPTTTT____SSSSPPPPIIIINNNNSSSS to a lower value, while
- applications with fewer pthreads may benefit from setting the
- environment variable to a higher value. If the environment variable
- is set to 0, these locks will all become blocking locks.
- _r_e_a_l_t_i_m_e(5) applications and applications that create only ssssyyyysssstttteeeemmmm
- ssssccccooooppppeeee threads may benefit from setting PPPPTTTT____SSSSPPPPIIIINNNNSSSS to 0. This forces
- the locks to block immediately instead of having the lock routine do
- a run-time check to determine if the caller is a ssssyyyysssstttteeeemmmm ssssccccooooppppeeee
- thread.
-
- TTTThhhhrrrreeeeaaaadddd DDDDaaaattttaaaa
- Pthreads share the address space; stacks, text and data are
- accessible by all threads in the process. This means that access to
- shared data is simpler than where multiple processes use a shared
- memory region which each must map. The cost is the potential for
- accidental corruption. Individual thread data is provided using the
- notion of a shared set of keys and unique thread values bound to
- each key. The _p_t_h_r_e_a_d__k_e_y__c_r_e_a_t_e() interface creates a new, shared
- key and _p_t_h_r_e_a_d__s_e_t_s_p_e_c_i_f_i_c() allows a thread to bind its own value
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- to a key. Conceptually, the key is an index to an array of values.
- The same key used by different threads may retrieve a different
- values because each thread has its own array.
-
- PPPPrrrroooocccceeeessssssss MMMMaaaannnnaaaaggggeeeemmmmeeeennnntttt
- Some basic UNIX interfaces have particular semantics when called
- from a POSIX threads process.
-
- ffffoooorrrrkkkk((((2222)))) creates a new pthread process and follows the usual rules
- for inherited state. The new process has a single pthread (the one
- which made the call); all other pthreads active prior to _f_o_r_k() are
- quietly destroyed and their resources (stacks etc.) reclaimed by the
- pthread run-time. A number of issues arise because _f_o_r_k() causes
- data to be copied from the parent to the child with no
- synchronisation with threads that may be modifying that data. To
- allow the application to perform its own synchronisation the
- _p_t_h_r_e_a_d__a_t_f_o_r_k() interface can register handlers to be processed
- when _f_o_r_k() is used. In general operations which are safe to
- perform after a _f_o_r_k() are the same as those which are safe to
- perform in a signal handler.
-
- eeeexxxxeeeecccc((((2222)))) overlays a new process image on the calling process; all
- threads from the old image are destroyed. Thread termination
- handlers and thread data destruction [see _p_t_h_r_e_a_d__c_l_e_a_n_u_p__p_u_s_h()
- and _p_t_h_r_e_a_d__k_e_y__c_r_e_a_t_e()] are not performed. The new process will
- only be a pthread process if the new image is of a pthread process.
-
- eeeexxxxiiiitttt((((2222)))) performs all the usual process clean up operations and then
- destroys all threads in the process. Thread termination handlers
- and thread data destruction [see _p_t_h_r_e_a_d__c_l_e_a_n_u_p__p_u_s_h() and
- _p_t_h_r_e_a_d__k_e_y__c_r_e_a_t_e()] are not performed.
-
- LLLLiiiimmmmiiiittttaaaattttiiiioooonnnnssss
- With POSIX threads there are some limitations and practices to avoid.
-
- NNNNooootttt eeeennnnoooouuuugggghhhh pppptttthhhhrrrreeeeaaaaddddssss
- Each pthread process has a resource limit called RRRRLLLLIIIIMMMMIIIITTTT____PPPPTTTTHHHHRRRREEEEAAAADDDD on
- the number of threads it can create. The value is inherited by
- child processes and may be set using _s_e_t_r_l_i_m_i_t(2) or the shell _l_i_m_i_t
- and _u_l_i_m_i_t commands. The default limits can be changed using the
- _s_y_s_t_u_n_e(1M) command on the _r_l_i_m_i_t__p_t_h_r_e_a_d__c_u_r and _r_l_i_m_i_t__p_t_h_r_e_a_d__m_a_x
- variables.
-
- FFFFaaaattttaaaallll eeeexxxxcccceeeeppppttttiiiioooonnnnssss
- When a thread executes code in the pthread run-time scheduler it
- masks signals so that signal handlers always run in a consistent
- environment. A side effect of this is that if the thread raises an
- exception (for example due to memory corruption) the kernel will
- terminate the process. As an aid to debugging such problems the
- environment variable PPPPTTTT____CCCCOOOORRRREEEE should be set prior to starting the
- application so that a core file will be generated.
-
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- pppptttthhhhrrrreeeeaaaaddddssss((((5555)))) pppptttthhhhrrrreeeeaaaaddddssss((((5555))))
-
-
-
- SSSSttttaaaacccckkkk oooovvvveeeerrrrrrrruuuunnnn
- Unlike the default stack in an unthreaded IRIX process, pthread
- stacks are limited [see _p_t_h_r_e_a_d__a_t_t_r__s_e_t_s_t_a_c_k_s_i_z_e()] and a thread
- may overrun its stack. By default pthread stacks have a protected
- region at the end of the stack [see _p_t_h_r_e_a_d__a_t_t_r__s_e_t_g_u_a_r_d_s_i_z_e()]
- that can turn some of these overruns into a protection faults which
- is generally preferable to overwriting data.
-
- DDDDyyyynnnnaaaammmmiiiicccc llllooooaaaaddddiiiinnnngggg
- The pthread library can be made available to a running process. The
- pthread DSO can be dynamically loaded using _d_l_o_p_e_n(3C) or
- _s_g_i_d_l_a_d_d(3C). Any pthread calls made before pthread library is
- loaded will all return ENOSYS.
-
- UUUUssssiiiinnnngggg sssspppprrrrooooccccssss
- The _s_p_r_o_c(2) model of threading is incompatible with POSIX threads.
- Attempts by an sproc process to create pthreads and vice-versa will
- be rejected.
-
- PPPPrrrriiiioooorrrriiiittttyyyy
- Attempts to create a pthread process at a priority outside of the
- valid range will be rejected [see _s_c_h_e_d__g_e_t__p_r_i_o_r_i_t_y__m_i_n(_2) and
- _s_c_h_e_d__g_e_t__p_r_i_o_r_i_t_y__m_a_x(_2)]. Specifically, _w_e_i_g_h_t_l_e_s_s is not a valid
- pthread priority.
-
- MMMMAAAAPPPP____LLLLOOOOCCCCAAAALLLL mmmmeeeemmmmoooorrrryyyy
- The POSIX thread memory model requires that memory be available to
- all threads. The MMMMAAAAPPPP____LLLLOOOOCCCCAAAALLLL option to _m_m_a_p(2) is useful only to
- sproc processes and should not be used with pthreads.
-
- DDDDyyyynnnnaaaammmmiiiicccc mmmmeeeemmmmoooorrrryyyy aaaallllllllooooccccaaaattttiiiioooonnnn
- The _s_b_r_k(2) call is not thread-safe. It is used by the C run-time
- memory allocator, _m_a_l_l_o_c(3C), which is always used by the pthread
- run-time. Safe use of _s_b_r_k(2) outside of the run-time (for example
- by a third party memory allocator) is not therefore possible.
-
- DDDDooooccccuuuummmmeeeennnnttttaaaattttiiiioooonnnn
- Additional on-line documentation about pthreads is available in:
- _T_o_p_i_c_s _i_n _I_R_I_X _P_r_o_g_r_a_m_m_i_n_g: _C_h_a_p_t_e_r _1_3
- _S_p_e_e_d_S_h_o_p _U_s_e_r'_s _G_u_i_d_e: _C_h_a_p_t_e_r _6
-
- SSSSEEEEEEEE AAAALLLLSSSSOOOO
- pthread_*(3P)
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-