|
POSIX Threads (Pthreads)
An Introduction |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
errno and Condition Codesint pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
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 |
Note:The new thread may start executing before pthread_create()
returns.
start() function returnsexit()
main()
pthread_exit()
int pthread_detach(pthread_t thread)
thread
|
The thread to detach |
| Return | 0 on success; a positive error number of error |
Note: Detaching a thread does not terminate it nor does it change the way in which a thread can/will be terminated.
int pthread_join(pthread_t thread, void **retval)
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 |
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).
-pthread
-pthread
#include <pthread.h>
#include <stdio.h> // For printf()
#include <stdlib.h> // For exit()
#include <string.h> // For strlen()
#include <unistd.h> // For sleep() if needed
static void
*display(void *arg)
{
char *s;
void *result;
// Demonstrate how to use the argument
s = (char *)arg; // Cast the void* as a char*
printf("%s\n", s); // Print
// Demonstrate how to return
result = (void *)(strlen(s)); // Cast the int as a void*
return result; // Return
}
int
main(void)
{
char *s;
long len;
pthread_t helper;
void *result;
s = "Department of Computer Science";
pthread_create(&helper, NULL, display, "JMU");
printf("%s\n", s);
pthread_join(helper, &result);
len = (long)result;
printf("Characters printed by the main thread: %ld\n", (long)(strlen(s)));
printf("Characters printed by the helper thread: %ld\n", len);
exit(0);
}
#include <pthread.h>
#include <stdio.h> // For printf()
#include <stdlib.h> // For exit()
#include <string.h> // For strlen()
#include <unistd.h> // For sleep() if needed
// A function that is used for many purposes
long
display(char *s)
{
printf("%s\n", s);
return strlen(s);
}
// A wrapper for display() so that it can be executed in a thread
static void
*display_wrapper(void *arg)
{
char *s;
long result;
s = (char *)arg;
result = display(s);
return (void *)result;
}
// The entry point of the program
int
main(void)
{
char *s;
long helper_len, main_len;
pthread_t helper;
void *result;
s = "Department of Computer Science";
pthread_create(&helper, NULL, display_wrapper, "JMU");
main_len = display(s);
pthread_join(helper, &result);
helper_len = (long)result;
printf("Characters printed by the main thread: %ld\n", main_len);
printf("Characters printed by the helper thread: %ld\n", helper_len);
exit(0);
}
#include <pthread.h>
#include <stdio.h> // For printf()
#include <stdlib.h> // For exit()
#include <string.h> // For strlen()
#include <unistd.h> // For sleep() if needed
// A function that is used for many purposes
long
display(char *s)
{
// Try adding calls to sleep() in various places
printf("%s\n", s);
printf("(Thread: %ld)\n", pthread_self());
printf("\n\n");
return strlen(s);
}
// A wrapper for display() so that it can be executed in a thread
static void
*display_wrapper(void *arg)
{
char *s;
long result;
// Try adding calls to sleep() in various places
s = (char *)arg;
result = display(s);
return (void *)result;
}
// The entry point of the program
int
main(void)
{
char *c, *d, *u;
pthread_t thread_c, thread_u;
void *result;
d = "Department of Computer Science";
c = "College of Integrated Science and Engineering";
u = "James Madison University";
display(d);
pthread_create(&thread_c, NULL, display_wrapper, c);
pthread_create(&thread_u, NULL, display_wrapper, u);
pthread_join(thread_c, &result);
pthread_join(thread_u, &result);
exit(0);
}
int pthread_once(pthread_once_t *control, void (*init)(void))
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 |
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().