Linux Tutorial - POSIX Threads
Linux Tutorial - POSIX Threads
html
The POSIX thread libraries are a standards based thread API for C/C++. It allows one to spawn a new
concurrent process flow. It is most effective on multi-processor or multi-core systems where the
process flow can be scheduled to run on another processor thus gaining speed through parallel or
distributed processing. Threads require less overhead than "forking" or spawning a new process
because the system does not initialize a new system virtual memory space and environment for the
process. While most effective on a multiprocessor system, gains are also found on uniprocessor
systems which exploit latency in I/O and other system functions which may halt process execution.
(One thread may execute while another is waiting for I/O or some other system latency.) Parallel
programming technologies such as MPI and PVM are used in a distributed computing environment
while threads are limited to a single computer system. All threads within a process share the same
address space. A thread is spawned by defining a function and its arguments which will be
processed in the thread. The purpose of using the POSIX thread library in your software is to execute
software faster.
Table of Contents:
# Thread Basics
# Thread Creation and
Termination
# Thread
Synchronization
# Thread Scheduling
# Thread Pitfalls
# Thread Debugging
# Thread Man Pages Congratulations, You are our 888,888th visitor!
# Links right now online That's why we've just selected you to be the our possible winner:
on 11/04/2011 - an Apple iMac - iPhone4 - iPad
# Books at 00:04 If selected: >>click here<<
Thread Basics:
Related YoLinux
Tutorials:
Thread operations include thread creation, termination, synchronization
° C++ on Linux (joins,blocking), scheduling, data management and process interaction.
A thread does not maintain a list of created threads, nor does it know the
° C++ STL (Standard thread that created it.
Template Library) example All threads within a process share the same address space.
of a linked list using a list
Threads in the same process share:
° C++ string class Process instructions
examples Most data
open files (descriptors)
° X-emacs and C++ signals and signal handlers
development current working directory
User and group id
° C++ Structure Example
and Tutorial Each thread has a unique:
Thread ID
° Linux software set of registers, stack pointer
development tutorial stack for local variables, return addresses
signal mask
°YoLinux Tutorials Index
priority
Return value: errno
pthread functions return "0" if OK.
Example: pthread1.c
01 #include <stdio.h>
1 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
02 #include <stdlib.h>
03 #include <pthread.h>
04
05 void *print_message_function( void *ptr );
06
07 main()
08 {
09 pthread_t thread1, thread2;
10 char *message1 = "Thread 1";
11 char *message2 = "Thread 2";
12 int iret1, iret2;
13
14 /* Create independent threads each of which will
execute function */
15
16 iret1 = pthread_create( &thread1, NULL,
print_message_function, (void*) message1);
17 iret2 = pthread_create( &thread2, NULL,
print_message_function, (void*) message2);
18
19 /* Wait till threads are complete before main
continues. Unless we */
20 /* wait we run the risk of executing an exit which
will terminate */
21 /* the process and all threads before the threads
have completed. */
22
23 pthread_join( thread1, NULL);
24 pthread_join( thread2, NULL);
25
26 printf("Thread 1 returns: %d\n",iret1);
27 printf("Thread 2 returns: %d\n",iret2);
28 exit(0);
29 }
30
31 void *print_message_function( void *ptr )
32 {
33 char *message;
34 message = (char *) ptr;
35 printf("%s \n", message);
36 }
Ads by Google
Linux Server
Linux Books Compile:
Linux Download
Tutorial
Linux OS Tutorial
C compiler: cc -lpthread pthread1.c
or
C++ compiler: g++ -lpthread pthread1.c
Free Information
Technology
Magazines and Run: ./a.out
Document Downloads Results:
Thread 1
Thread 2
Thread 1 returns: 0
Thread 2 returns: 0
Details:
In this example the same function is used in each thread. The arguments
are different. The functions need not be the same.
Free Information Threads terminate by explicitly calling pthread_exit, by letting the function
Technology Software return, or by a call to the function exit which will terminate the process
and Development including any threads.
Magazine
Subscriptions and Function call: pthread_create - create a new thread
Document Downloads
int pthread_create(pthread_t * thread,
const pthread_attr_t * attr,
void * (*start_routine)(void *),
void *arg);
Arguments:
thread - returns the thread id. (unsigned long int defined in
2 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
bits/pthreadtypes.h)
attr - Set to NULL if default thread attributes are used. (else define
members of the struct pthread_attr_t defined in bits/pthreadtypes.h)
Attributes include:
detached state (joinable? Default: PTHREAD_CREATE_JOINABLE. Other
option: PTHREAD_CREATE_DETACHED)
scheduling policy (real-time?
PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)
scheduling parameter
inheritsched attribute (Default: PTHREAD_EXPLICIT_SCHED Inherit from
parent thread: PTHREAD_INHERIT_SCHED)
scope (Kernel threads: PTHREAD_SCOPE_SYSTEM User threads:
PTHREAD_SCOPE_PROCESS Pick one or the other not both.)
guard size
stack address (See unistd.h and bits/posix_opt.h
_POSIX_THREAD_ATTR_STACKADDR)
stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h),
void * (*start_routine) - pointer to the function to be threaded.
Function has a single argument: pointer to void.
*arg - pointer to argument of function. To pass multiple arguments,
send a pointer to a structure.
Arguments:
th - thread suspended until the thread identified by th terminates,
either by calling pthread_exit() or by being cancelled.
thread_return - If thread_return is not NULL, the return value of th is
stored in the location pointed to by thread_return.
Arguments:
retval - Return value of thread.
This routine kills the thread. The pthread_exit function never returns. If the
thread is not detached, the thread id and return value may be examined
from another thread by using pthread_join.
Note: the return pointer *retval, must not be of local scope otherwise it
would cease to exist once the thread terminates.
[C++ pitfalls]: The above sample program will compile with the GNU C and
C++ compiler g++. The following function pointer representation below will
work for C but not C++. Note the subtle differences and avoid the pitfall
below:
Thread Synchronization:
3 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Mutexes:
If register load and store operations for the incrementing of variable counter
occurs with unfortunate timing, it is theoretically possible to have each thread
increment and overwrite the same variable with the same value. Another
possibility is that thread two would first increment counter locking out thread one
until complete and then thread one would increment it to 2.
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <pthread.h>
04
05 void *functionC();
06 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
07 int counter = 0;
08
09 main()
10 {
11 int rc1, rc2;
4 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Man Pages:
Joins:
A join is performed when one wants to wait for a thread to finish. A thread calling
routine may launch multiple threads then wait for them to finish to get the results.
One waits for the completion of the threads with a join.
01 #include <stdio.h>
02 #include <pthread.h>
03
04 #define NTHREADS 10
5 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Man Pages:
Condition Variables:
6 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Creating/Destroying:
pthread_cond_init
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_destroy
Waiting on condition:
pthread_cond_wait - unlocks the mutex and waits for the condition
variable cond to be signaled.
pthread_cond_timedwait - place limit on how long it will block.
Waking thread based on condition:
pthread_cond_signal - restarts one of the threads that are waiting on
the condition variable cond.
pthread_cond_broadcast - wake up all threads blocked by the
specified condition variable.
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <pthread.h>
04
05 pthread_mutex_t count_mutex =
PTHREAD_MUTEX_INITIALIZER;
06 pthread_cond_t condition_var =
PTHREAD_COND_INITIALIZER;
07
08 void *functionCount1();
09 void *functionCount2();
10 int count = 0;
11 #define COUNT_DONE 10
12 #define COUNT_HALT1 3
13 #define COUNT_HALT2 6
14
15 main()
16 {
17 pthread_t thread1, thread2;
18
19 pthread_create( &thread1, NULL, &functionCount1, NULL);
20 pthread_create( &thread2, NULL, &functionCount2, NULL);
21
22 pthread_join( thread1, NULL);
23 pthread_join( thread2, NULL);
24
25 printf("Final count: %d\n",count);
26
27 exit(0);
28 }
29
30 // Write numbers 1-3 and 8-10 as permitted by
functionCount2()
31
32 void *functionCount1()
33 {
34 for(;;)
35 {
36 // Lock mutex and then wait for signal to relase
mutex
37 pthread_mutex_lock( &count_mutex );
38
39 // Wait while functionCount2() operates on count
40 // mutex unlocked if condition varialbe in
functionCount2() signaled.
41 pthread_cond_wait( &condition_var, &count_mutex );
42 count++;
43 printf("Counter value functionCount1: %d\n",count);
44
45 pthread_mutex_unlock( &count_mutex );
46
47 if(count >= COUNT_DONE) return(NULL);
48 }
49 }
50
51 // Write numbers 4-7
52
53 void *functionCount2()
54 {
7 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
55 for(;;)
56 {
57 pthread_mutex_lock( &count_mutex );
58
59 if( count < COUNT_HALT1 || count > COUNT_HALT2 )
60 {
61 // Condition of if statement has been met.
62 // Signal to free waiting thread by freeing the
mutex.
63 // Note: functionCount1() is now permitted to
modify "count".
64 pthread_cond_signal( &condition_var );
65 }
66 else
67 {
68 count++;
69 printf("Counter value functionCount2:
%d\n",count);
70 }
71
72 pthread_mutex_unlock( &count_mutex );
73
74 if(count >= COUNT_DONE) return(NULL);
75 }
76
77 }
Note that functionCount1() was halted while count was between the values
COUNT_HALT1 and COUNT_HALT2. The only thing that has been ensures is
that functionCount2 will increment the count between the values COUNT_HALT1
and COUNT_HALT2. Everything else is random.
The logic conditions (the "if" and "while" statements) must be chosen to insure
that the "signal" is executed if the "wait" is ever processed. Poor software logic
can also lead to a deadlock condition.
Note: Race conditions abound with this example because count is used as the
condition and can't be locked in the while statement without causing deadlock.
Thread Scheduling:
When this option is enabled, each thread may have its own scheduling
properties. Scheduling attributes may be specified:
The threads library provides default values that are sufficient for most cases.
Thread Pitfalls:
Race conditions: While the code may appear on the screen in the order you
wish the code to execute, threads are scheduled by the operating system
8 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Thread safe code: The threaded routines must call functions which are
"thread safe". This means that there are no static or global variables which
other threads may clobber or read assuming single threaded operation. If
static or global variables are used then mutexes must be applied or the
functions must be re-written to avoid the use of these variables. In C, local
variables are dynamically allocated on the stack. Therefore, any function
that does not use static data or other shared resources is thread-safe.
Thread-unsafe functions may be used by only one thread at a time in a
program and the uniqueness of the thread must be ensured. Many
non-reentrant functions return a pointer to static data. This can be avoided
by returning dynamically allocated data or using caller-provided storage. An
example of a non-thread safe function is strtok which is also not
re-entrant. The "thread safe" version is the re-entrant version strtok_r.
Mutex Deadlock: This condition occurs when a mutex is applied but then
not "unlocked". This causes program execution to halt indefinitely. It can
also be caused by poor application of mutexes or joins. Be careful when
applying two or more mutexes to a section of code. If the first
pthread_mutex_lock is applied and the second pthread_mutex_lock fails
due to another thread applying a mutex, the first mutex may eventually lock
all other threads from accessing data including the thread which holds the
second mutex. The threads may wait indefinitely for the resource to become
free causing a deadlock. It is best to test and if failure occurs, free the
resources and stall before retrying.
01 ...
02 pthread_mutex_lock(&mutex_1);
03 while ( pthread_mutex_trylock(&mutex_2) ) /* Test if
already locked */
04 {
05 pthread_mutex_unlock(&mutex_1); /* Free resource to
avoid deadlock */
06 ...
07 /* stall here */
08 ...
09 pthread_mutex_lock(&mutex_1);
10 }
11 count++;
12 pthread_mutex_unlock(&mutex_1);
13 pthread_mutex_unlock(&mutex_2);
14 ...
The order of applying the mutex is also important. The following code
segment illustrates a potential for deadlock:
01 void *function1()
02 {
03 ...
04 pthread_mutex_lock(&lock1); // Execution step
1
05 pthread_mutex_lock(&lock2); // Execution step
3 DEADLOCK!!!
06 ...
07 ...
08 pthread_mutex_lock(&lock2);
09 pthread_mutex_lock(&lock1);
10 ...
11 }
12
13 void *function2()
14 {
15 ...
16 pthread_mutex_lock(&lock2); // Execution step
2
17 pthread_mutex_lock(&lock1);
18 ...
9 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
19 ...
20 pthread_mutex_lock(&lock1);
21 pthread_mutex_lock(&lock2);
22 ...
23 }
24
25 main()
26 {
27 ...
28 pthread_create(&thread1, NULL, function1, NULL);
29 pthread_create(&thread2, NULL, function2, NULL);
30 ...
31 }
If function1 acquires the first mutex and function2 acquires the second, all
resources are tied up and locked.
Condition Variable Deadlock: The logic conditions (the "if" and "while"
statements) must be chosen to insure that the "signal" is executed if the
"wait" is ever processed.
Thread Debugging:
GDB:
Debugging Programs with Multiple Threads
GDB: Stopping and starting multi-thread programs
GDB/MI: Threads commands
DDD:
Examining Threads
10 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Links:
11 of 12 4/11/2011 2:34 PM
Linux Tutorial: POSIX Threads http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
News Groups:
comp.programming.threads
comp.unix.solaris
Books:
12 of 12 4/11/2011 2:34 PM