THREADS, LIKE PROCESSES, ARE A MECHANISM TO ALLOW A PROGRAM
to do more than
one thing at a time.As with processes, threads appear to run
concurrently; the Linux
kernel schedules them asynchronously, interrupting each
thread from time to time to
give others a chance to execute.
Conceptually, a thread exists within a process.Threads are a
finer-grained unit of
execution than processes.When you invoke a program, Linux
creates a new process
and in that process creates a single thread, which runs the program
sequentially.That
thread can create additional threads; all these threads run
the same program in the
same process, but each thread may be executing a different
part of the program at any
given time.
We’ve seen how a program can fork a child process.The child
process is initially
running its parent’s program, with its parent’s virtual
memory, file descriptors, and so
on copied.The child process can modify its memory, close
file descriptors, and the like
without affecting its parent, and vice versa.When a program
creates another thread,
though, nothing is copied.The creating and the created
thread share the same memory
space, file descriptors, and other system resources as the
original. If one thread changes
the value of a variable, for instance, the other thread
subsequently will see the modified
value. Similarly, if one thread closes a file descriptor,
other threads may not read
from or write to that file descriptor. Because a process and
all its threads can be executing
only one program at a time, if any thread inside a process
calls one of the exec
functions, all the other threads are ended (the new program
may, of course, create new
threads).
GNU/Linux implements the POSIX standard thread API (known as
pthreads). All
thread functions and data types are declared in the header
file <pthread.h>.The
pthread functions are not included in the standard C
library. Instead, they are in
libpthread, so you should add -lpthread to the command line
when you link your
program.
4.1 Thread Creation
Each thread in a process is identified by a thread ID.When
referring to thread IDs in
C or C++ programs, use the type pthread_t.
Upon creation, each thread executes a thread function.This
is just an ordinary function
and contains the code that the thread should run.When the
function returns, the
thread exits. On GNU/Linux, thread functions take a single
parameter, of type void*,
and have a void* return type.The parameter is the thread
argument: GNU/Linux passes
the value along to the thread without looking at it.Your
program can use this parameter
to pass data to a new thread. Similarly, your program can
use the return value to
pass data from an exiting thread back to its creator.
The pthread_create function creates a new thread.You provide
it with the following:
1. A pointer to a pthread_t variable, in which the thread ID
of the new thread is
stored.
2. A pointer to a thread attribute object.This object
controls details of how the
thread interacts with the rest of the program. If you pass
NULL as the thread
attribute, a thread will be created with the default thread
attributes.Thread
attributes are discussed in Section 4.1.5,“Thread
Attributes.”
3. A pointer to the thread function.This is an ordinary
function pointer, of this
type:
void* (*) (void*)
4. A thread argument value of type void*. Whatever you pass
is simply passed as
the argument to the thread function when the thread begins
executing.
A call to pthread_create returns immediately, and the
original thread continues executing
the instructions following the call. Meanwhile, the new
thread begins executing
the thread function. Linux schedules both threads
asynchronously, and your program
must not rely on the relative order in which instructions
are executed in the two
threads.
The program in
Listing 4.1 creates a thread that prints x’s continuously to standard
error. After
calling pthread_create, the main thread prints o’s
continuously to standard
error.
Listing 4.1 (thread-create.c) Create a Thread
#include
<pthread.h>
#include
<stdio.h>
/* Prints x’s to
stderr. The parameter is unused. Does not return. */
void* print_xs
(void* unused)
{
while (1)
fputc (‘x’,
stderr);
return NULL;
}
/* The main
program. */
int main ()
{
pthread_t
thread_id;
/* Create a new
thread. The new thread will run the print_xs
function. */
pthread_create
(&thread_id, NULL, &print_xs, NULL);
/* Print o’s
continuously to stderr. */
while (1)
fputc (‘o’,
stderr);
return 0;
}
Compile and link
this program using the following code:
% cc -o
thread-create thread-create.c -lpthread
Try running it
to see what happens. Notice the unpredictable pattern of x’s and o’s as
Linux
alternately schedules the two threads.
Under normal
circumstances, a thread exits in one of two ways. One way, as illustrated
previously, is
by returning from the thread function.The return value from the
thread function
is taken to be the return value of the thread. Alternately, a thread can
exit explicitly
by calling pthread_exit.This function
may be called from within the
thread function
or from some other function called directly or indirectly by the thread
function.The
argument to pthread_exit is the thread’s
return value.
No comments:
Post a Comment