📄 posix threads programming.htm
字号:
src="POSIX Threads Programming.files/page01.gif" width=20 align=top>
<B><SPAN class=heading3>Example Code - Pthread Creation and
Termination</SPAN>
<P><FONT size=-1><PRE><B>
<FONT color=red>#include <pthread.h></FONT>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
printf("\n%d: Hello World!\n", threadid);
<FONT color=red>pthread_exit(NULL);</FONT>
}
int main (int argc, char *argv[])
{
<FONT color=red>pthread_t threads[NUM_THREADS];</FONT>
int rc, t;
for(t=0;t < NUM_THREADS;t++){
printf("Creating thread %d\n", t);
<FONT color=red>rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);</FONT>
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
<FONT color=red>pthread_exit(NULL);</FONT>
}
</B></PRE><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello.c"
target=W2><IMG height=20 alt="View source code"
src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A>
<A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello.out"
target=W2><IMG height=20 alt="View sample output"
src="POSIX Threads Programming.files/output1.gif" width=65 border=0></A>
</FONT></B></TD></TR></TBODY></TABLE></P></LI></UL><!---------------------------------------------------------------------------><A
name=PassingArguments><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>Passing Arguments to Threads </SPAN>
<P><BR>
<UL>
<P>
<LI>The <TT>pthread_create()</TT> routine permits the programmer to pass one
argument to the thread start routine. For cases where multiple arguments must
be passed, this limitation is easily overcome by creating a structure which
contains all of the arguments, and then passing a pointer to that structure in
the <TT>pthread_create()</TT> routine.
<P></P>
<LI>All arguments must be passed by reference and cast to (void *).
<P></P></LI></UL>
<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: How can you safely pass data to newly created threads, given
their non-deterministic start-up and scheduling? <BR><INPUT onclick="Answers('pthreads02')" type=button value=Answer></TD></TR></TBODY></TABLE>
<UL>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><IMG height=22
src="POSIX Threads Programming.files/page01.gif" width=20 align=top>
<B><SPAN class=heading3>Example 1 - Thread Argument Passing</SPAN></B>
<UL>This code fragment demostrates how to pass a simple integer to
each thread. The calling thread uses a unique data structure for each
thread, insuring that each thread's argument remains intact throughout
the program. </UL>
<HR>
<FONT size=-1><PRE><B>
int *taskids[NUM_THREADS];
for(t=0;t < NUM_THREADS;t++)
{
taskids[t] = (int *) malloc(sizeof(int));
*taskids[t] = t;
printf("Creating thread %d\n", t);
<FONT color=red>rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) taskids[t]);</FONT>
...
}
</B></PRE><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg1.c"
target=W2><IMG height=20 alt="View source code"
src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A>
<A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg1.out"
target=W2><IMG height=20 alt="View sample output"
src="POSIX Threads Programming.files/output1.gif" width=65 border=0></A>
</FONT></TD></TR></TBODY></TABLE>
<P><BR>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><IMG height=22
src="POSIX Threads Programming.files/page01.gif" width=20 align=top>
<B><SPAN class=heading3>Example 2 - Thread Argument Passing</SPAN></B>
<UL>This example shows how to setup/pass multiple arguments via a
structure. Each thread receives a unique instance of the structure.
</UL>
<HR>
<FONT size=-1><PRE><B>
struct thread_data{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
struct thread_data *my_data;
...
my_data = (struct thread_data *) threadarg;
taskid = my_data->thread_id;
sum = my_data->sum;
hello_msg = my_data->message;
...
}
int main (int argc, char *argv[])
{
...
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
<FONT color=red>rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) &thread_data_array[t]);</FONT>
...
}
</B></PRE><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg2.c"
target=W2><IMG height=20 alt="View source code"
src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A>
<A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg2.out"
target=W2><IMG height=20 alt="View sample output"
src="POSIX Threads Programming.files/output1.gif" width=65 border=0></A>
</FONT></TD></TR></TBODY></TABLE>
<P><BR>
<TABLE cellSpacing=0 cellPadding=5 width="90%" border=1>
<TBODY>
<TR>
<TD bgColor=#eeeeee><IMG height=22
src="POSIX Threads Programming.files/page01.gif" width=20 align=top>
<B><SPAN class=heading3>Example 3 - Thread Argument Passing</SPAN>
(Incorrect)</B>
<UL>This example performs argument passing incorrectly. The loop which
creates threads modifies the contents of the address passed as an
argument, possibly before the created threads can access it. </UL>
<HR>
<FONT size=-1><PRE><B>
int rc, t;
for(t=0;t < NUM_THREADS;t++)
{
printf("Creating thread %d\n", t);
<FONT color=red>rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) &t);</FONT>
...
}
</B></PRE><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg3.c"
target=W2><IMG height=20 alt="View source code"
src="POSIX Threads Programming.files/source1.gif" width=65 border=0></A>
<A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/samples/hello_arg3.out"
target=W2><IMG height=20 alt="View sample output"
src="POSIX Threads Programming.files/output1.gif" width=65 border=0></A>
</FONT></TD></TR></TBODY></TABLE></P></UL><!---------------------------------------------------------------------------><A
name=ThreadIdentifiers><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>Thread Identifiers </SPAN>
<P><BR>
<UL>
<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_self.html"
target=W2>pthread_self</A> ()
<P><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_equal.html"
target=W2>pthread_equal</A> (thread1,thread2)
</P></B></TT></TD></TR></TBODY></TABLE>
<P></P>
<LI>The <TT>pthread_self()</TT> routine returns the unique, system assigned
thread ID of the calling thread.
<P></P>
<LI>The <TT>pthread_equal()</TT> routine compares two thread IDs. If the two
IDs are different 0 is returned, otherwise a non-zero value is returned.
<P></P>
<LI>Note that for both of these routines, the thread identifier objects are
opaque and can not be easily inspected. Because thread IDs are opaque objects,
the C language equivalence operator <TT>==</TT> should not be used to compare
two thread IDs against each other, or to compare a single thread ID against
another value. </LI></UL><!---------------------------------------------------------------------------><A
name=Joining><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>Joining Threads </SPAN>
<P><BR>
<UL>
<P>
<LI>"Joining" is one way to accomplish synchronization between threads. Two
other ways, mutexes and condition variables will be discussed later.
<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_join.html"
target=W2>pthread_join</A> (threadid,status)
</B></TT></TD></TR></TBODY></TABLE>
<P></P>
<LI>The <TT>pthread_join()</TT> subroutine blocks the calling thread until the
specified <I>threadid</I> thread terminates.
<P></P>
<LI>The programmer is able to obtain the target thread's termination return
status if specified through <TT>pthread_exit()</TT>, in the <I>status</I>
parameter.
<P></P>
<LI>It is impossible to join a detached thread (discussed next) </LI></UL><!---------------------------------------------------------------------------><A
name=Detaching><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>Detaching / Joining Threads </SPAN>
<P><BR>
<UL>
<P>
<LI>When a thread is created, one of its attributes defines whether it is
joinable or detached. Detached means it can never be joined.
<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_attr_init.html"
target=W2>pthread_attr_init</A> (attr)
<P><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_attr_setdetachstate.html"
target=W2>pthread_attr_setdetachstate</A> (attr,detachstate)
<P><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_attr_getdetachstate.html"
target=W2>pthread_attr_getdetachstate</A> (attr,detachstate)
<P><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_attr_destroy.html"
target=W2>pthread_attr_destroy</A> (attr)
<P><A onclick=blur()
href="http://www.llnl.gov/computing/tutorials/workshops/workshop/pthreads/man/pthread_join.html"
target=W2>pthread_detach</A> (threadid,status)
</P></B></TT></TD></TR></TBODY></TABLE>
<P></P>
<LI>To explicitly create a thread as joinable or detached, the <TT>attr</TT>
argument in the <TT>pthread_create()</TT> routine is used. The typical 4 step
process is:
<OL>
<LI>Declare a pthread attribute variable of the <TT>pthread_attr_t</TT> data
type
<LI>Initialize the attribute variable with <TT>pthread_attr_init()</TT>
<LI>Set the attribute detached status with
<TT>pthread_attr_setdetachstate()</TT>
<LI>When done, free library resources used by the attribute with
<TT>pthread_attr_destroy()</TT> </LI></OL>
<P></P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -