- Forward


POSIX Threads (Pthreads)
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Review
Back SMYC Forward
  • Program:
    • A file containing machine language instructions, the entry-point address, data, symbol and relocation tables, and other information
  • Process:
    • An instance of a program execution
Review (cont.)
Back SMYC Forward
  • Flow of Control:
    • A sequence of control transfers (i.e., transitions between instructions/steps)
  • Concurrent Flows:
    • Two flows, \(X\) and \(Y\), are said to running concurrently iff \(Y\) began after \(X\) began and before \(X\) finished or \(X\) began after \(Y\) began and before \(Y\) finished
Motivation
Back SMYC Forward
  • Threads:
    • A mechanism that allows for concurrent flows within a single process
  • Advantages Over Multiple Processes:
    • The sharing information between threads is easy and fast
    • The creation of threads is faster than the creation of processes
Organization
Back SMYC Forward
  • Text Segment:
    • All threads share the same program code (though they can be executing different parts)
  • Data Segments:
    • All threads share the same uninitialized and initialized data segments
Organization (cont.)
Back SMYC Forward
  • Heap:
    • All threads share the same heap
  • Stack:
    • Each thread has its own stack (in the stack space for the process)
Organization (cont.)
Back SMYC Forward
thread-memory-organization
Attributes
Back SMYC Forward
  • Shared:
    • Process ID, Process Group ID, and Session ID
    • Controlling Terminal
    • Credentials
    • Open File Descriptors
    • Record Locks
    • Signal Dispositions (making signals difficult to use)
    • Current Working Directory, Root Directory, etc...
    • Timers
    • Resource Limits
  • Unique (a.k.a. Thread Context):
    • Thread ID
    • Signal Mask
    • errno and Condition Codes
    • Stack and Stack Pointer
    • Program Counter
    • General Purpose Register Values
Thread Creation: pthread_create() pthread_create
Back SMYC Forward
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
Purpose:
Create a new thread
Details:
thread Identifier of the new thread
start The function to be executed in the new thread
attr Attributes of the new thread (or NULL to use the default attributes)
arg The argument to pass to start()
Return 0 on success; a positive error number on error
#include <pthread.h> pthread.h

Note:The new thread may start executing before pthread_create() returns.

Thread Termination
Back SMYC Forward
  • "Dropping Out":
    • The thread's start() function returns
  • Process Termination:
    • Any thread calls exit()
    • The main thread returns from main()
  • Forced Termination:
    • pthread_exit()
"Forced" Thread Termination: pthread_exit() pthread_exit
Back SMYC Forward
void pthread_exit(void *retval)
Purpose:
Terminate the calling thread
Details:
retval The return value for the thread
#include <pthread.h> pthread.h

Note:The value pointed to by retval must not be on the thread's stack.

Detaching: pthread_detach() pthread_detach
Back SMYC Forward
int pthread_detach(pthread_t thread)
Purpose:
Indicate that you don't care about the thread's return status and that the kernel should remove the thread when it terminates
Details:
thread The thread to detach
Return 0 on success; a positive error number of error
#include <pthread.h> pthread.h

Note: Detaching a thread does not terminate it nor does it change the way in which a thread can/will be terminated.

Joining: pthread_join() pthread_join
Back SMYC Forward
int pthread_join(pthread_t thread, void **retval)
Purpose:
Wait for a thread to terminate
Details:
thread The thread to wait for
retval A non-NULL pointer that receives a copy of the terminated thread's return value
Return 0 on success; a positive error number on error
#include <pthread.h> pthread.h

Notes: (1) If thread has already terminated then pthread_join() will return immediately. (2) One must not call pthread_join() on a thread that has already been joined (since the ID may have been re-used).

Cleaning Up
Back SMYC Forward
  • Remember:
    • One must either detach a thread or join with it (otherwise resources will be wasted)
  • An Intentional Limitation:
    • One must join with a particular thread (i.e., one can't join with any undetached thread) since (unlike with processes) there is no thread hierarchy
Building Multi-Threaded Programs
Back SMYC Forward
  • Compiling:
    • -pthread
  • Linking:
    • -pthread
A Simple Example
Back SMYC Forward
unixexamples/pthreads/messager.c
 
Wrapper Functions
Back SMYC Forward
  • Normally:
    • The function that a thread first executes is written exclusively for that purpose
  • Sometimes:
    • The function is of more general applicability in which case it is convenient to write a wrapper function
Wrapper Functions (cont.)
Back SMYC Forward
unixexamples/pthreads/wrapper.c
 
Thread IDs: pthread_self() pthread_self
Back SMYC Forward
pthread_t pthread_self(void)
Purpose:
Obtain the calling thread's thread ID
Details:
Return The thread ID of the calling thread
#include <pthread.h> pthread.h
Comparing Thread IDs: pthread_equal() pthread_equal
Back SMYC Forward
int pthread_equal(pthread_t a, pthread_t b)
Purpose:
Check to see if two thread IDs refer to the same thread
Details:
a The ID of one thread
b The ID of abother thread
Return 0 if unequal; nonzero otherwise
#include <pthread.h> pthread.h
Thread IDs (cont.)
Back SMYC Forward
unixexamples/pthreads/id.c
 
One-Time Initialization: pthread_once() pthread_once
Back SMYC Forward
int pthread_once(pthread_once_t *control, void (*init)(void))
Purpose:
Ensure that a function is executed once (regardless of how many threads are created)
Details:
control Pointer to a statically initialized variable with the value PTHREAD_ONCE_INIT
init Pointer to the function that is to be executed once
Return 0 on success; positive error number on error
#include <pthread.h> pthread.h

The first call to pthread_once() modifies the value of the variable pointed to by control and then calls init(). Subsequent calls to pthread_once() then don't call init().

There's Always More to Learn
Back -