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