📄 posix threads programming.htm
字号:
inter-process communication.
<P></P>
<LI>Threaded applications offer potential performance gains and practical
advantages over non-threaded applications in several other ways:
<UL>
<LI>Overlapping CPU work with I/O: For example, a program may have sections
where it is performing a long I/O operation. While one thread is waiting for
an I/O system call to complete, CPU intensive work can be performed by other
threads.
<LI>Priority/real-time scheduling: tasks which are more important can be
scheduled to supersede or interrupt lower priority tasks.
<LI>Asynchronous event handling: tasks which service events of indeterminate
frequency and duration can be interleaved. For example, a web server can
both transfer data from previous requests and manage the arrival of new
requests. </LI></UL>
<P></P>
<LI>The primary motivation for considering the use of Pthreads on an SMP
architecture is to achieve optimum performance. In particular, if an
application is using MPI for on-node communications, there is a potential that
performance could be greatly improved by using Pthreads for on-node data
transfer instead.
<P></P>
<LI>For example: IBM's MPI provides the MP_SHARED_MEMORY environment variable
to direct the use of shared memory for on-node MPI communications instead of
switch communications. Without this, on-node MPI communications demonstrate
serious performance degradation as the number of tasks increase.
<P>However, even with MP_SHARED_MEMORY set to "yes", on-node MPI
communications can not compete with Pthreads:
<P>
<UL>
<LI>IBM 604e shared memory MPI bandwidth: @80 MB/sec per MPI task
<LI>IBM POWER3 NH-2 shared memory MPI bandwidth: @275 MB/sec per MPI task
<LI>Pthreads worst case: Every data reference by a thread requires a memory
read. In this case, a thread's "bandwidth" is limited by the machine's
memory-to-CPU bandwidth: <BR>604e: 1.3 GB/sec <BR>POWER3 NH-2: 16 GB/sec
<LI>Pthreads best case: Data is local to a thread's cache offering much
greater cache-CPU bandwidths. </LI></UL></LI></UL><!---------------------------------------------------------------------------><A
name=Designing><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD background="POSIX Threads Programming.files/bg2.gif"
bgColor=navy><SPAN class=heading1>Pthreads Overview
</SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Designing Threaded Programs </SPAN>
<P><BR>
<UL>
<P>
<LI>In order for a program to take advantage of Pthreads, it must be able to
be organized into discrete, independent tasks which can execute concurrently.
For example, if routine1 and routine2 can be interchanged, interleaved and/or
overlapped in real time, they are candidates for threading.
<P>
<CENTER><IMG height=254 src="POSIX Threads Programming.files/concurrent.gif"
width=360 border=0> </CENTER>
<P></P>
<LI>Tasks that may be suitable for threading include tasks that:
<UL>
<LI>Block for potentially long waits
<LI>Use many CPU cycles
<LI>Must respond to asynchronous events
<LI>Are of lesser or greater importance than other tasks
<LI>Are able to be performed in parallel with other tasks </LI></UL>
<P></P>
<LI>Be careful if your application uses libraries or other objects that don't
explicitly guarantee thread-safeness. When in doubt, assume that they are not
thread-safe until proven otherwise.
<P></P>
<LI>Several common models for threaded programs exist:
<UL>
<P>
<LI><B><I>Manager/worker:</I></B> a single thread, the <I>manager</I>
assigns work to other threads, the <I>workers</I>. Typically, the manager
handles all input and parcels out work to the other tasks. At least two
forms of the manager/worker model are common: static worker pool and dynamic
worker pool.
<P></P>
<LI><B><I>Pipeline:</I></B> a task is broken into a series of suboperations,
each of which is handled in series, but concurrently, by a different thread.
An automobile assembly line best describes this model.
<P></P>
<LI><B><I>Peer:</I></B> similar to the manager/worker model, but after the
main thread creates other threads, it participates in the work.
</LI></UL></LI></UL><!---------------------------------------------------------------------------><A
name=PthreadsAPI><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD background="POSIX Threads Programming.files/bg2.gif"
bgColor=navy><SPAN class=heading1>The Pthreads
API</SPAN></TD></SPAN></TD></TD></TR></TBODY></TABLE>
<P><BR>
<UL>
<P>
<LI>The Pthreads API is defined in the ANSI/IEEE POSIX 1003.1 - 1995 standard.
Unlike MPI, this standard is not freely available on the Web - it must be <A
href="http://standards.ieee.org/catalog/posix.html">purchased from IEEE</A>.
<P></P>
<LI>The subroutines which comprise the Pthreads API can be informally grouped
into three major classes:
<OL>
<P>
<LI><B><I>Thread management:</I></B> The first class of functions work
directly on threads - creating, detaching, joining, etc. They include
functions to set/query thread attributes (joinable, scheduling etc.)
<P></P>
<LI><B><I>Mutexes:</I></B> The second class of functions deal with
synchronization, called a "mutex", which is an abbreviation for "mutual
exclusion". Mutex functions provide for creating, destroying, locking and
unlocking mutexes. They are also supplemented by mutex attribute functions
that set or modify attributes associated with mutexes.
<P></P>
<LI><B><I>Condition variables:</I></B> The third class of functions address
communications between threads that share a mutex. They are based upon
programmer specified conditions. This class includes functions to create,
destroy, wait and signal based upon specified variable values. Functions to
set/query condition variable attributes are also included. </LI></OL>
<P></P>
<LI>Naming conventions: All identifiers in the threads library begin with
<B>pthread_</B>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TH bgColor=#eeeeee><SPAN class=heading3>Routine Prefix </SPAN>
<TH bgColor=#eeeeee><SPAN class=heading3>Functional Group </SPAN>
<TR>
<TD><B>pthread_</B>
<TD>Threads themselves and miscellaneous subroutines
<TR>
<TD><B>pthread_attr_</B>
<TD>Thread attributes objects
<TR>
<TD><B>pthread_mutex_</B>
<TD>Mutexes
<TR>
<TD><B>pthread_mutexattr_</B>
<TD>Mutex attributes objects.
<TR>
<TD><B>pthread_cond_</B>
<TD>Condition variables
<TR>
<TD><B>pthread_condattr_</B>
<TD>Condition attributes objects
<TR>
<TD><B>pthread_key_</B>
<TD>Thread-specific data keys </TR></TBODY></TABLE>
<P></P>
<LI>The concept of opaque objects pervades the design of the API. The basic
calls work to create or modify opaque objects - the opaque objects can be
modified by calls to attribute functions, which deal with opaque attributes.
<P></P>
<LI>The Pthreads API contains over 60 subroutines. This tutorial will focus on
a subset of these - specifically, those which are most likely to be
immediately useful to the beginning Pthreads programmer.
<P></P>
<LI>The <TT>pthread.h</TT> header file must be included in each source file
using the Pthreads library.
<P></P>
<LI>The current POSIX standard is defined only for the C language. Fortran
programmers can use wrappers around C function calls. Also, the IBM Fortran
compiler provides a Pthreads API. See the XLF Language Reference, located with
<A
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/MAIN.html#IBMDocs">IBM's
Fortran documentation</A> for more information.
<P></P>
<LI>A number of excellent books about Pthreads are available. Several of these
are listed in the <A
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/MAIN.html#References">References
</A>section of this tutorial. </LI></UL><!---------------------------------------------------------------------------><A
name=Management><BR><BR></A><A name=CreatingThreads></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD background="POSIX Threads Programming.files/bg2.gif"
bgColor=navy><SPAN class=heading1>Thread Management
</SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Creating Threads </SPAN>
<P><BR>
<UL>
<P>
<LI>Initially, your <TT>main()</TT> program comprises a single, default
thread. All other threads must be explicitly created by the programmer.
<P></P>
<LI>Routines:
<P>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><TT><B><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_create.html"
target=W2>pthread_create</A> (thread,attr,start_routine,arg)
</B></TT></TD></TR></TBODY></TABLE>
<P></P>
<LI>This routine creates a new thread and makes it executable. Typically,
threads are first created from within <TT>main()</TT> inside a single process.
Once created, threads are peers, and may create other threads.
<P></P>
<LI>The pthread_create subroutine returns the new thread ID via the
<I>thread</I> argument. The caller can use this thread ID to perform various
operations on the thread. This ID should be checked to ensure that the thread
was successfully created.
<P></P>
<LI>The <I>attr</I> parameter is used to set thread attributes. You can
specify a thread attributes object, or NULL for the default values. Thread
attributes are discussed later.
<P></P>
<LI>The <I>start_routine</I> is the C routine that the thread will execute
once it is created.
<P></P>
<LI>A single argument may be passed to <I>start_routine</I> via <I>arg</I>. It
must be passed by reference as a pointer cast of type void.
<P></P>
<LI>The maximum number of threads that may be created by a process is
implementation dependent. </LI></UL>
<P>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD width=15></TD>
<TD><IMG height=32 src="POSIX Threads Programming.files/question2.gif"
width=27></TD>
<TD>Question: After a thread has been created, how do you know when it
will be scheduled to run by the operating system...especially on an SMP
machine? <BR><INPUT onclick="Answers('pthreads01')" type=button value=Answer></TD></TR></TBODY></TABLE><!---------------------------------------------------------------------------><A
name=TerminatingThreads><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD background="POSIX Threads Programming.files/bg2.gif"
bgColor=navy><SPAN class=heading1>Thread Management
</SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Terminating Thread Execution </SPAN>
<P><BR>
<UL>
<P>
<LI>There are several ways in which a Pthread may be terminated:
<UL>
<LI>The thread returns from its starting routine (the main routine for the
initial thread).
<LI>The thread makes a call to the <TT>pthread_exit</TT> subroutine (covered
below).
<LI>The thread is canceled by another thread via the <TT>pthread_cancel</TT>
routine (not covered here).
<LI>The entire process is terminated due to a call to either the exec or
exit subroutines. </LI></UL>
<P></P>
<LI>Routines:
<P>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><TT><B><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_exit.html"
target=W2>pthread_exit</A> (status) </B></TT></TD></TR></TBODY></TABLE>
<P></P>
<LI>This routine is used to explicitly exit a thread. Typically, the
<TT>pthread_exit()</TT> routine is called after a thread has completed its
work and is no longer required to exist.
<P></P>
<LI>If <TT>main()</TT> finishes before the threads it has created, and exits
with <TT>pthread_exit()</TT>, the other threads will continue to execute.
Otherwise, they will be automatically terminated when <TT>main()</TT>
finishes.
<P></P>
<LI>The programmer may optionally specify a termination <I>status</I>, which
is stored as a void pointer for any thread that may join the calling thread.
<P></P>
<LI>Cleanup: the <TT>pthread_exit()</TT> routine does not close files; any
files opened inside the thread will remain open after the thread is
terminated.
<P></P>
<LI>Recommendation: Use <TT>pthread_exit()</TT> to exit from all
threads...especially <TT>main()</TT>. </LI></UL><!---------------------------------------------------------------------------><A
name=CreateExample><BR><BR></A>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD background="POSIX Threads Programming.files/bg2.gif"
bgColor=navy><SPAN class=heading1>Thread Management
</SPAN></TD></TD></TR></TBODY></TABLE>
<P><SPAN class=heading2>Example: Pthread Creation and Termination </SPAN>
<P><BR>
<UL>
<P>
<LI>This simple example code creates 5 threads with the
<TT>pthread_create()</TT> routine. Each thread prints a "Hello World!"
message, and then terminates with a call to <TT>pthread_exit()</TT>.
<P>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><IMG height=22
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -