1
+ #define _GNU_SOURCE
2
+
3
+ #include <errno.h>
4
+ #include <fcntl.h>
5
+ #include <pthread.h>
6
+ #include <signal.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <sys/mman.h>
11
+ #include <sys/stat.h>
12
+ #include <sys/types.h>
13
+ #include <unistd.h>
14
+ #include <semaphore.h>
15
+ #define ERR (source ) \
16
+ (fprintf(stderr, "%s:%d\n", __FILE__, __LINE__), perror(source), kill(0, SIGKILL), exit(EXIT_FAILURE))
17
+ #define SEM_NAME "my_sem2"
18
+ #define SHM_NAME "my_shm2"
19
+
20
+ typedef struct
21
+ {
22
+ int intialised ,counter ,hits ,samples ;
23
+ pthread_mutex_t mutex ;
24
+ } shared_data_t ;
25
+
26
+
27
+ void usage (char * name )
28
+ {
29
+ fprintf (stderr , "USAGE: %s N\n" , name );
30
+ exit (EXIT_FAILURE );
31
+ }
32
+
33
+ void TryInitSharedData (shared_data_t * shared_data )
34
+ {
35
+ if (shared_data -> intialised != 1 ){
36
+ shared_data -> intialised = 1 ;
37
+ shared_data -> counter = 0 ;
38
+ shared_data -> hits = 0 ;
39
+ shared_data -> samples = 0 ;
40
+ pthread_mutexattr_t attr ;
41
+ pthread_mutexattr_init (& attr );
42
+ pthread_mutexattr_setpshared (& attr , PTHREAD_PROCESS_SHARED );
43
+ pthread_mutexattr_setrobust (& attr , PTHREAD_MUTEX_ROBUST );
44
+ pthread_mutex_init (& shared_data -> mutex , & attr );
45
+ }
46
+ }
47
+
48
+ void MutexLock (pthread_mutex_t * mutex )
49
+ {
50
+ int error ;
51
+ if ((error = pthread_mutex_lock (mutex )) != 0 )
52
+ {
53
+ if (error == EOWNERDEAD )
54
+ {
55
+ if ((error = pthread_mutex_consistent (mutex )) != 0 )
56
+ ERR ("pthread_mutex_consistent" );
57
+ }
58
+ else
59
+ ERR ("pthread_mutex_lock" );
60
+ }
61
+ }
62
+
63
+ void CleanUp ()
64
+ {
65
+ sem_unlink (SEM_NAME );
66
+ shm_unlink (SHM_NAME );
67
+ }
68
+
69
+ int MonteCarlo (int N ){
70
+ int M = 0 ;
71
+ for (int i = 0 ; i < N ; i ++ )
72
+ {
73
+ double x = (double )rand () / RAND_MAX ;
74
+ double y = (double )rand () / RAND_MAX ;
75
+ if (x * x + y * y <= 1 )
76
+ M ++ ;
77
+ }
78
+ return M ;
79
+ }
80
+
81
+ void DoWork (int N , shared_data_t * shared_data )
82
+ {
83
+ for (int i = 0 ; i < 3 ;i ++ ){
84
+ int result = MonteCarlo (N );
85
+ MutexLock (& shared_data -> mutex );
86
+ shared_data -> hits = shared_data -> hits + result ;
87
+ shared_data -> samples = shared_data -> samples + N ;
88
+ fprintf (stderr , "Current Values: hits = %d, samples = %d\n" , shared_data -> hits , shared_data -> samples );
89
+ pthread_mutex_unlock (& shared_data -> mutex );
90
+ sleep (1 );
91
+ }
92
+ }
93
+
94
+ int main (int argc , char * argv [])
95
+ {
96
+ if (argc != 2 )
97
+ usage (argv [0 ]);
98
+
99
+ int N = atoi (argv [1 ]);
100
+
101
+ srand (getpid ());
102
+
103
+ sem_t * sem = sem_open (SEM_NAME , O_CREAT , 0666 , 1 );
104
+
105
+ int shm_fd = shm_open (SHM_NAME , O_RDWR | O_CREAT ,0666 );
106
+ ftruncate (shm_fd , sizeof (shared_data_t ));
107
+
108
+ char * shm_ptr = mmap (NULL , sizeof (shared_data_t ), PROT_READ | PROT_WRITE , MAP_SHARED , shm_fd , 0 );
109
+ if (shm_ptr == MAP_FAILED )
110
+ ERR ("shm_open" );
111
+
112
+ shared_data_t * shared_data = (shared_data_t * )shm_ptr ;
113
+
114
+ //shared_data->intialised = 0;
115
+
116
+ if (sem_trywait (sem ) == 0 )
117
+ TryInitSharedData (shared_data );
118
+ sem_post (sem );
119
+ sem_close (sem );
120
+
121
+ MutexLock (& shared_data -> mutex );
122
+ shared_data -> counter = shared_data -> counter + 1 ;
123
+ pthread_mutex_unlock (& shared_data -> mutex );
124
+
125
+ DoWork (N , shared_data );
126
+
127
+ MutexLock (& shared_data -> mutex );
128
+ shared_data -> counter = shared_data -> counter - 1 ;
129
+ if (shared_data -> counter == 0 )
130
+ {
131
+ fprintf (stderr ,"Final result: pi = %f\n" , 4.0 * shared_data -> hits / shared_data -> samples );
132
+ pthread_mutex_unlock (& shared_data -> mutex );
133
+ pthread_mutex_destroy (& shared_data -> mutex );
134
+ munmap (shm_ptr , sizeof (shared_data_t ));
135
+ CleanUp ();
136
+ }
137
+ else
138
+ pthread_mutex_unlock (& shared_data -> mutex );
139
+ return EXIT_SUCCESS ;
140
+ }
0 commit comments