User Tools

Site Tools


cs:posix:threads_example1
Return to Home page

Threads Example 1

Concepts:
Example regarding basic functionalities of POSIX threads

Text:
Implement an example program that highlights the main functionalities of threads.

Solution:

threads_example1.c
/* 
   - Creation of the threads with pthread_create()
   - Exchange with the threads of a structure with different values for each thread
   - Exchange with the main of the returned value of a thread
   - Wait a thread with pthread_join()
   - Global variables and threads
*/
 
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>
 
#define N_THREAD 3
 
 
/* Global variable, all the threads can see this variable, if a thread modify the value of the variable, all the other threads see the modified value. Important: variables cannot be modified by more than one thread at a time, otherwise a race condition is generated. */
int global_variable = 10;
 
 
typedef struct {
  int thread_num;
  char letter;
} my_t;
 
 
static void *process (void *arg)
{
  int i;
  my_t *param = (my_t *) arg;	// cast the void argument to the real type
 
  if (param->thread_num == 0) global_variable = 20;
  fprintf (stdout, "Starting thread %d, letter=%c, global_variable=%d\n", param->thread_num, param->letter, global_variable);
  for (i = 0; i < 10; i++) 
    write (STDOUT_FILENO, &(param->letter), 1); /* By default, when a process is executed the file descriptors number 0, 1 and 2 are automatically opened, and assigned to stdin, stdout and stderr, respectivelly */
  printf("\n");
  param->letter = toupper(param->letter);
  pthread_exit(&(param->letter));
}
 
 
int main (void)
{
  int retcode;
  pthread_t th[N_THREAD];
  char *retval;
  my_t value[N_THREAD];
  int i = 0;
 
  for(i=0; i<N_THREAD; i++){
    value[i].letter = 'a'+i;
  }
 
  for(i=0; i<N_THREAD; i++){
    value[i].thread_num = i;
    retcode = pthread_create (&th[i], NULL, process, (void *) &(value[i]));
    if (retcode != 0)
      fprintf (stderr, "pthread_create failed %d\n", retcode);
  }
 
 
  for(i=0; i<N_THREAD; i++){
 
    retcode = pthread_join (th[i], (void *)&retval);
    if (retcode != 0)
      fprintf (stderr, "pthread_join failed %d\n", retcode);
 
    fprintf(stdout, "retval : %c\n", *(retval) );
 }
 
  return 0;
}

Comments:
This example shows how to pass a structure to threads (in pthread_create()). Each thread must work on its own data (i.e., its own element of the vector of structures), otherwise it is possible that the data it reads is modified by the main() in the meanwhile, and it contains the data for the following thread generated by pthread_create().

Threads return a results (a data) to the main(), in particular each thread transforms the letter passed by the main in uppercase, and it returns back it to the main() by means of pthread_exit() and pthread_join(). Look the pointers, and in particular remember that the memory area containing the data cannot be a variable inside the thread, because its memory is de-allocated when the thread finishes.

The output of the threads is printed in an interleaved way because they are executed concurrently.

Global variable can be accessed by all the thread. If you want to modify them, you need to do it in a non concurrent way. To this purpose semaphores can be employed.

Compilation:
To compile the program type the following command:

gcc -Wall -o threads_example threads_example1.c -lpthread

If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it

You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/cs/posix/threads_example1
/web/htdocs/www.skenz.it/home/data/pages/cs/posix/threads_example1.txt · Last modified: 2019/11/22 18:54 by zioskenz

Privacy Policy