Lesson of 3 March 2011¶
Introduction to pthread
A first example
File thread-esempio1.cc
1#include <iostream>
2#include <stdlib.h>
3#include <unistd.h>
4
5#include <pthread.h>
6
7using namespace std ;
8
9#define NUM_THREADS 5
10
11pthread_mutex_t mutex_var = PTHREAD_MUTEX_INITIALIZER ;
12
13typedef struct { int numThread ; } ParameterForThread ;
14
15extern "C"
16void *
17PrintHello( void * thePars )
18{
19 // thePars contains a pointer to the data passed in the
20 // call of pthread_create (last parameter)
21 ParameterForThread * pars = static_cast<ParameterForThread*>(thePars) ;
22
23 unsigned sn = (rand()%3)+1 ;
24
25 sleep(sn) ;
26
27 pthread_mutex_lock(&mutex_var) ; // block other thread until unlock
28 cerr << "\nThread n. " << pars -> numThread << " sleep = " << sn << " Hello World!\n" ;
29 pthread_mutex_unlock(&mutex_var) ;
30
31 pthread_exit(NULL) ; // exit and release resource for the thread
32 return NULL ;
33}
34
35int
36main (int argc, char *argv[])
37{
38 pthread_t threads[NUM_THREADS] ;
39 ParameterForThread pars[NUM_THREADS] ;
40
41 for ( int t = 0 ; t < NUM_THREADS ; ++t ) {
42 pars[t] . numThread = t ;
43 cout << "Creating thread N. " << t << endl ;
44 int rc = pthread_create(&threads[t], // storage for thread information
45 NULL,
46 PrintHello, // the called thread
47 static_cast<void*>(&pars[t]) ); // data passed to the thread
48
49 if ( rc ) {
50 cerr << "ERROR; return code from pthread_create() is " << rc << "\n" ;
51 exit(-1);
52 }
53 }
54
55 pthread_exit(NULL); /* aspetta che the thread abbiano finito */
56
57 return 0 ;
58}
A second example
File thread-esempio2.cc
1#include <iostream>
2#include <stdlib.h>
3#include <unistd.h>
4
5#include <pthread.h>
6
7using namespace std ;
8
9#define NUM_THREADS 5
10
11pthread_mutex_t mutex_var = PTHREAD_MUTEX_INITIALIZER ;
12
13typedef struct { int numThread ; } ParameterForThread ;
14
15extern "C"
16void *
17PrintHello( void * thePars )
18{
19 // thePars contains a pointer to the data passed in the
20 // call of pthread_create (last parameter)
21 ParameterForThread * pars = static_cast<ParameterForThread*>(thePars) ;
22
23 long sn = (rand()%3)+1 ;
24
25 sleep(sn) ;
26
27 pthread_mutex_lock(&mutex_var) ; // block other thread until unlock
28 cerr << "\nThread n. " << pars -> numThread << " sleep = " << sn << " Hello World!\n" ;
29 pthread_mutex_unlock(&mutex_var) ;
30
31 pthread_exit((void*)sn) ; // exit and release resource for the thread
32 return NULL ;
33}
34
35int
36main (int argc, char *argv[])
37{
38 pthread_t threads[NUM_THREADS] ;
39 ParameterForThread pars[NUM_THREADS] ;
40
41 for ( int t = 0 ; t < NUM_THREADS ; ++t ) {
42 pars[t] . numThread = t ;
43 cout << "Creating thread N. " << t << endl ;
44 int rc = pthread_create(&threads[t], // storage for thread information
45 NULL,
46 PrintHello, // the called thread
47 static_cast<void*>(&pars[t]) ); // data passed to the thread
48
49 if ( rc ) {
50 cerr << "ERROR; return code from pthread_create() is " << rc << "\n" ;
51 exit(-1);
52 }
53 }
54
55 // wait until all the thread has finisched
56 cout << "Wait!\n" ;
57 for ( int t = 0 ; t < NUM_THREADS ; ++t ) {
58 void * return_value ;
59 if ( pthread_join(threads[t], &return_value) ) {
60 cerr << "Error while waiting for thread N." << t << '\n' ;
61 exit(1) ;
62 }
63 pthread_mutex_lock(&mutex_var) ; // block other thread until unlock
64 cout << "Thread N. " << t << " returned " << (long) return_value << '\n' ;
65 pthread_mutex_unlock(&mutex_var) ; // block other thread until unlock
66 }
67
68 cout << "ALL DONE\n" ;
69
70 return 0 ;
71}
A third example
File thread-esempio3.cc
1#include <iostream>
2#include <stdlib.h>
3#include <unistd.h>
4#include <vector>
5
6#include <pthread.h>
7
8using namespace std ;
9
10#define NUM_THREADS 5
11
12pthread_mutex_t mutex_var = PTHREAD_MUTEX_INITIALIZER ;
13
14typedef struct { int numThread ; } ParameterForThread ;
15
16// struct which contains the arguments passed to the thread
17struct arguments {
18 vector<double> array ;
19 double sum ;
20} ;
21
22bool stop = true ;
23
24// compute the sum of the element of the array
25void * do_work( void *arg ) {
26 struct arguments * argument = (struct arguments*)arg ;
27 argument -> sum = 0 ;
28 while ( stop ) ;
29 for ( int i = 0 ; i < argument -> array . size() ; ++i ) {
30 argument -> sum += argument -> array[i] ;
31 }
32 pthread_exit(NULL) ;
33}
34
35int
36main(int argc, char *argv) {
37 void * return_value;
38 pthread_t worker_thread;
39 struct arguments arg ;
40
41 arg . array . reserve(100000) ;
42 for ( int i=0 ; i < 100000 ; ++i )
43 arg . array . push_back( (rand()%256) / 123.923) ;
44
45 if ( pthread_create(&worker_thread, NULL, do_work, (void *) &arg) ) {
46 cerr << "Error while creating thread\n" ;
47 exit(1);
48 }
49
50 sleep(1) ;
51 stop = false ;
52 int a = 1 ;
53 cout << "Valore argomento " << arg . sum << '\n' ;
54 a = a + 1 ;
55 cout << "Valore argomento " << arg . sum << '\n' ;
56 a = a + 1 ;
57 cout << "Valore argomento " << arg . sum << '\n' ;
58 a = a + 1 ;
59 cout << "Valore argomento " << arg . sum << '\n' ;
60 a = a + 1 ;
61 cout << "Valore argomento " << arg . sum << '\n' ;
62 a = a + 1 ;
63 cout << "Valore argomento " << arg . sum << '\n' ;
64 a = a + 1 ;
65 cout << "Valore argomento " << arg . sum << '\n' ;
66 a = a + 1 ;
67 cout << "Valore argomento " << arg . sum << '\n' ;
68 a = a + 1 ;
69 cout << "Valore argomento " << arg . sum << '\n' ;
70 a = a + 1 ;
71
72 // wait the thread
73 if ( pthread_join(worker_thread, &return_value) ) {
74 cerr << "Error while waiting for thread\n" ;
75 exit(1);
76 }
77 cout << "Valore argomento dopo JOIN " << arg . sum << '\n' ;
78
79 pthread_exit(NULL) ;
80 return 0 ;
81}
A NOT working solution of the Philosophes problem
A first example
File thread-filosofi-1.cc
1/*
2 Versione NON funzionante del problema dei filosofi.
3*/
4
5#include <pthread.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9
10#define N_FILOSOFI 5
11
12pthread_mutex_t mutex_var ;
13
14typedef enum { PENSO, MANGIO, DORMO } STATO_FILOSOFO ;
15typedef enum { LIBERA, INUSO } STATO_FORCHETTE ;
16
17static STATO_FILOSOFO stato_filosofo[N_FILOSOFI] ;
18static STATO_FORCHETTE stato_forchetta[N_FILOSOFI] ;
19
20void
21prende_forchetta_destra( int const n ) {
22 pthread_mutex_lock(&mutex_var) ; /* manca controllo sulla chiamata */
23 int f_destra = (n+1) % N_FILOSOFI ;
24 if ( stato_forchetta[f_destra] == INUSO ) {
25 printf("Filosofo N.%d aspetta la forchetta destra\n",n) ;
26 while ( stato_forchetta[f_destra] == INUSO ) ; /* aspetto che si liberi la forchetta */
27 }
28 stato_forchetta[f_destra] = INUSO ; /* si accaparra la forchetta */
29 printf("Filosofo N.%d prende la forchetta destra\n",n) ;
30 pthread_mutex_unlock(&mutex_var) ;
31}
32
33void
34prende_forchetta_sinistra( int const n) {
35 pthread_mutex_lock(&mutex_var) ; /* manca controllo sulla chiamata */
36 int f_sinistra = n ;
37 if ( stato_forchetta[f_sinistra] == INUSO ) {
38 printf("Filosofo N.%d aspetta la forchetta sinistra\n",n) ;
39 while ( stato_forchetta[f_sinistra] == INUSO ) ; /* aspetto che si liberi la forchetta */
40 }
41 stato_forchetta[f_sinistra] = INUSO ; /* si accaparra la forchetta */
42 printf("Filosofo N.%d prende la forchetta sinistra\n",n) ;
43 pthread_mutex_unlock(&mutex_var) ;
44}
45
46void
47lascia_forchetta_destra( int const n ) {
48 pthread_mutex_lock(&mutex_var) ; /* manca controllo sulla chiamata */
49 int f_destra = (n+1) % N_FILOSOFI ;
50 stato_forchetta[f_destra] == LIBERA ;
51 printf("Filosofo N.%d lascia la forchetta destra\n",n) ;
52 pthread_mutex_unlock(&mutex_var) ;
53}
54
55void
56lascia_forchetta_sinistra( int const n) {
57 pthread_mutex_lock(&mutex_var) ; /* manca controllo sulla chiamata */
58 int f_sinistra = n ;
59 stato_forchetta[f_sinistra] == LIBERA ;
60 printf("Filosofo N.%d lascia la forchetta sinistra\n",n) ;
61 pthread_mutex_unlock(&mutex_var) ;
62}
63
64void *
65filosofo(void *arg) {
66 long n = (long) arg ;
67
68 while ( 1 ) { /* ciclo infinito */
69 /* pensa */
70 stato_filosofo[n] = PENSO ;
71 printf("Il filosofo N.%ld PENSA\n", n) ;
72 prende_forchetta_destra( n ) ;
73 prende_forchetta_sinistra( n ) ;
74
75 /* mangia */
76 stato_filosofo[n] = MANGIO ;
77 printf("Il filosofo N.%ld MANGIA\n", n) ;
78 lascia_forchetta_destra( n ) ;
79 lascia_forchetta_sinistra( n ) ;
80
81 /* dorme */
82 stato_filosofo[n] = DORMO ;
83 printf("Il filosofo N.%ld DORME\n", n) ;
84 //sleep(1) ;
85 }
86 pthread_exit(NULL) ;
87}
88
89void *
90monitor(void *arg) {
91 int i ;
92 while ( 1 ) { /* ciclo infinito */
93 sleep(1) ; /* aspetta un secondo */
94 printf("\nFILOSOFI: ") ;
95 for ( i = 0 ; i < N_FILOSOFI ; ++i ) {
96 switch ( stato_filosofo[i] ) {
97 case PENSO: printf(" P") ; break ;
98 case MANGIO: printf(" M") ; break ;
99 case DORMO: printf(" D") ; break ;
100 }
101 }
102 printf("\nFORCHETTE: ") ;
103 for ( i = 0 ; i < N_FILOSOFI ; ++i ) {
104 switch ( stato_forchetta[i] ) {
105 case LIBERA: printf(" L") ; break ;
106 case INUSO: printf(" U") ; break ;
107 }
108 }
109 printf("\n") ;
110 }
111 pthread_exit(NULL) ;
112}
113
114int
115main(int argc, char *argv) {
116 int i ;
117 pthread_t filosofo_thread[N_FILOSOFI], monitor_thread ;
118
119 if ( pthread_mutex_init(&mutex_var, NULL) ) {
120 /* inizializzo la variabile per il mutex */
121 printf("Error while creating mutex\n");
122 exit(1);
123 }
124
125 for ( i = 0 ; i < N_FILOSOFI ; ++i ) {
126 stato_filosofo[i] = DORMO ;
127 stato_forchetta[i] = LIBERA ;
128 }
129
130 for ( i = 0 ; i < N_FILOSOFI ; ++i ) {
131 printf("Creo il filosofo N.%d\n", i) ;
132 if ( pthread_create(&filosofo_thread[i], NULL, filosofo, (void *) i) ) {
133 printf("Error while creating thread\n");
134 exit(1);
135 }
136 }
137 if ( pthread_create(&monitor_thread, NULL, monitor, NULL) ) {
138 printf("Error while creating thread\n");
139 exit(1);
140 }
141
142 pthread_exit(NULL) ;
143 return 0 ;
144}