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()
.