POSIX Threads and Semaphores
This document describes the system calls to create and manage threads
in the HP-UX version of Unix. This calls are similar to those
found in Windows NT
- Threads
- Thread type
- Prototype function for a thread
- Thread Creation constants
- Create a thread
- Wait for a thread
- Other thread calls
- Semaphores
- Semaphore type
- Initializing a semaphore
- Semaphore operations
Threads [top
]
Thread Type [top
]
The thread header file to include is pthread.h. This header file
contains the definition of a type, pthread_t. This type is
basically an integer (On hawk, it is just defined as an unsigned int
). Its use is as a thread identifier.
Example: Declare two variables t1, and t2 to hold thread id's:
#include <pthread.h>
pthread_t t1, t2;
Prototype function for a thread [top
]
The system call that creates a thread is passed the name of a function
in the program code which that thread will execute. The prototype of this
function must be like this function declaration of f. That is, one parameter
of type void * and a return type, also void *. This is
not a great restriction since the parameter can be the address of any
item. It does generally require that the function use a conversion (or cast)
on the parameter before using it.
void * f(void *p);
If f expects p to be a pointer to a double, then f might be written
like this:
void * f(void *p)
{
double *dp = (double *) p;
double y;
y = *dp;
// do something with the double value in y
...
return NULL;
}
Thread Creation Constants [top
]
When a thread is to be created in HP-UX a flag needs to be passed to the
system call to let the kernel know how to treast the thread. The value
to pass is defined as a symbolic constant in pthread.h and is of type
int.
#include <pthread.h>
pthread_att_t flags;
flags = NULL;
Create a thread [top
]
The system call to create a thread is:
int pthread_create(
pthread_t *pthr_id,
long flags,
void * (*pthr_func)(void *),
void * pthr_arg
);
where,
pthr_func |
the function for the thread to execute |
pthr_arg |
the argument to pass to the thread's function when it starts flags
the creation flags |
pthr_id |
the address of a thread_t variable. the function will copy
the new thread id into this variable. |
The return value is 0 if successful.
Wait for a thread [top
]
A thread that creates other threads can wait for any one of these threads
to finish or for a particular one to finish by calling the following function.
int pthread_join(pthread_t waitfor_thr,
void **status);
where,
waitfor_thr |
thread id of a particular thread to wait for. Can be 0. |
status |
Address of a variable. If not 0, thr_join copies the exit status
of the terminated thread. |
Other Thread Calls [top
]
A running thread can get its own thread id by calling pthread_self().
A thread can exit but not terminate any other thread in the process by
calling pthread_exit(): A thread can yield the processor for
one time by calling pthread_yield().
void pthread_exit(void *status);
thread_t pthread_self();
void sched_yield();
where status is either 0 or the address of a variable in which
to store the exit status of the thread.
Semaphores [top
]
Semaphore type [top
]
The semaphore header file contains the definition of a semaphore type,
sem_t. This type is a structure with several data members. However, you will
not directly use any of the data members. The only way to use a semaphore
is through the two functions that provide atomic operations on the semaphore.
You can use the semaphore type to declare a semaphore variable, but it is
not properly initialized by this declaration. A separate system call is the
only way to properly initialize the semaphore.
To use Semaphores, you must link in the realtime library by specifying -
lrt on the compiler or linker command line.
Example.
#include <sys/semaphore.h>
sem_t s;
Initializing a semaphore [top
]
The system call to initialize a semaphore is sem_init.
int sem_init(sem_t *sp, int type, unsigned int count);
where,
sp |
address of the semaphore variable to be initialized |
count |
the initial value of the integer part of the semaphore |
type |
a constant to indicate in processes or across process use. |
The return value is 0 if successful.
Example:
#include <sys/semaphore.h>
sem_t s;
if ( sem_init(&s, NULL, 1) != 0 )
{
// Error: initialization failed
}
Semaphore Operations [top
]
The two operations on a properly initialized semaphore are sem_wait
and sem_post:
int sem_wait(sem_t *sp);
int sem_post(sem_t *sp);
Example:
sem_t s;
// Assume sem_init has been called to initialize s.
sem_wait(&s);
....
sem_post(&s);