Pthreads are created using pthread_create().
#include <pthread.h> int pthread_create (pthread_t *thread_id, const pthread_attr_t *attributes, void *(*thread_function)(void *), void *arguments);
This function creates a new thread. pthread_t is an opaque type which acts as a handle for the new thread. attributes is another opaque data type which allows you to fine tune various parameters, to use the defaults pass NULL. thread_function is the function the new thread is executing, the thread will terminate when this function terminates, or it is explicitly killed. arguments is a void * pointer which is passed as the only argument to the thread_function.
Pthreads terminate when the function returns, or the thread can call pthread_exit() which terminates the calling thread explicitly.
int pthread_exit (void *status);
status is the return value of the thread. (note a thread_function returns a void *, so calling return(void *) is the equivalent of this function.
One Thread can wait on the termination of another by using pthread_join()
int pthread_join (pthread_t thread, void **status_ptr);
The exit status is returned in status_ptr.
A thread can get its own thread id, by calling pthread_self()
pthread_t pthread_self ();
Two thread id's can be compared using pthread_equal()
int pthread (pthread_t t1, pthread_t t2);
Returns zero if the threads are different threads, non-zero otherwise.
Mutexes have two basic operations, lock and unlock. If a mutex is unlocked and a thread calls lock, the mutex locks and the thread continues. If however the mutex is locked, the thread blocks until the thread 'holding' the lock calls unlock.
There are 5 basic functions dealing with mutexes.
int pthread_mutex_init (pthread_mutex_t *mut, const pthread_mutexattr_t *attr);
Note that you pass a pointer to the mutex, and that to use the default attributes just pass NULL for the second parameter.
int pthread_mutex_lock (pthread_mutex_t *mut);
Locks the mutex :).
int pthread_mutex_unlock (pthread_mutex_t *mut);
Unlocks the mutex :).
int pthread_mutex_trylock (pthread_mutex_t *mut);
Either acquires the lock if it is available, or returns EBUSY.
int pthread_mutex_destroy (pthread_mutex_t *mut);
Deallocates any memory or other resources associated with the mutex.
Consider the problem we had before, now lets use mutexes:
THREAD 1 THREAD 2 pthread_mutex_lock (&mut); pthread_mutex_lock (&mut); a = data; /* blocked */ a++; /* blocked */ data = a; /* blocked */ pthread_mutex_unlock (&mut); /* blocked */ b = data; b--; data = b; pthread_mutex_unlock (&mut); [data is fine. The data race is gone.]
<<< Contents >>>