/[livstidsfanger]/trunk/livstidsfanger.c
ViewVC logotype

Diff of /trunk/livstidsfanger.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 9 by trond, 2014-11-07T12:40:00Z Revision 14 by trond, 2014-11-09T15:30:18Z
# Line 1  Line 1 
1  // Programmet bruker ISO C 2011 (ISO/IEC 9899:2011) og Pthreads (IEEE Std 1003.1c-1995). -*- coding: utf-8 -*-  // Programmet bruker ISO C 2011 (ISO/IEC 9899:2011) og Pthreads (IEEE Std 1003.1c-2001). -*- coding: utf-8 -*-
2  // Løsning programmert av Trond Endrestøl <Trond.Endrestol@ximalas.info>, 2014-11-06.  // Løsning programmert av Trond Endrestøl <Trond.Endrestol@ximalas.info>, 2014-11-06.
3    
4  // $Ximalas$  // $Ximalas$
5    
6    #if __STDC_VERSION__ < 199901L
7    #error det er tvilsomt om du får kompilert denne kildekoden med så gammel C-kompilator
8    #endif
9    
10  #include <errno.h>  #include <errno.h>
11  #include <pthread.h>  #include <pthread.h>
12  #include <signal.h>  #include <signal.h>
13  #include <stdbool.h>  #include <stdbool.h>
14  #include <stdio.h>  #include <stdio.h>
15  #include <stdlib.h>  #include <stdlib.h>
16  #include <string.h>  #include <string.h>
17  #include <time.h>  #include <time.h>
18  #include <unistd.h>  #include <unistd.h>
19    
20    #if _POSIX_THREADS < 200112L
21    #error her mangler det støtte for POSIX Threads anno 2001
22    #endif
23    
24  #if __STDC_VERSION__ >= 201112L  #if __STDC_VERSION__ >= 201112L
25  #include <stdnoreturn.h>  #include <stdnoreturn.h>
26  #else  #else
27  #define noreturn  #define noreturn
28  #endif  #endif
29    
30  #define ANTALL_LIVSTIDSFANGER 19U  #define ANTALL_LIVSTIDSFANGER 19U
31    
32  static unsigned antallBesok[ANTALL_LIVSTIDSFANGER];  static unsigned antallBesok[ANTALL_LIVSTIDSFANGER];
33    
34  static size_t tellendeLivstidsfange;  static size_t tellendeLivstidsfange;
35  static unsigned antallLivstidsfanger;  static unsigned antallLivstidsfanger;
36    
37  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
38  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
39  static bool brytere[2U];  static bool brytere[2U];
40    
41  noreturn void *livstidsfange(void *arg);  noreturn void *livstidsfange(void *arg);
42  void visResultater(void);  void visResultater(void);
43  void signalhandler(int sig);  void signalhandler(int sig);
44    
45  noreturn int main(int argc, char **argv)  noreturn int main(int argc, char **argv)
46  {  {
47    size_t i;    size_t i;
48    pthread_t tid = pthread_self();    pthread_t tid = pthread_self();
49    
50    atexit(visResultater);    if (argc >= 0) { // Bare for å få clang til å ti stille.
51    signal(SIGINT, signalhandler);      atexit(visResultater);
52        signal(SIGINT, signalhandler);
53      } // if
54    
55  #ifdef __FreeBSD__  #ifdef __FreeBSD__
56    srandomdev();    srandomdev();
57  #else  #else
58    srandom((unsigned int)time(NULL));    srandom((unsigned int)time(NULL));
59  #endif  #endif
60    
61    memset((void *)&antallBesok, 0, sizeof(antallBesok));    memset((void *)&antallBesok, 0, sizeof(antallBesok));
62    brytere[0] = random() & 1;    brytere[0] = random() & 1;
63    brytere[1] = random() & 1;    brytere[1] = random() & 1;
64    
65    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;
66    
67    printf("bryter %u er i utgangspunktet vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");    printf("bryter %u er i utgangspunktet vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
68    printf("bryter %u er i utgangspunktet vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");    printf("bryter %u er i utgangspunktet vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
69    printf("livstidsfange %zu er utpekt som den tellende livstidsfange\n\n", tellendeLivstidsfange + 1);    printf("livstidsfange %zu er utpekt som den tellende livstidsfange\n\n", tellendeLivstidsfange + 1);
70    
71    puts("maintråden venter på å få låst mutex");    puts("maintråden venter på å få låst mutex");
72    pthread_mutex_lock(&mutex);    pthread_mutex_lock(&mutex);
73    puts("mutex er låst av maintråden");    puts("mutex er låst av maintråden");
74    
75    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {
76      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);
77    
78      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {
79          fflush(stdout);
80        fprintf(stderr,        fprintf(stderr,
81                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",
82                argv[0], i, strerror(errno), errno);                argv[0], i, strerror(errno), errno);
83        exit(1);        fflush(stderr);
84          _exit(1);
85      } // if      } // if
86    } // for    } // for
87    
88    // maintråden påtar seg rolla som fengselsdirektøren.    // maintråden påtar seg rolla som fengselsdirektøren.
89    while (1) {    while (1) {
90      puts("fengselsdirektøren låser opp mutex");      puts("fengselsdirektøren låser opp mutex");
91      pthread_mutex_unlock(&mutex);      pthread_mutex_unlock(&mutex);
92      puts("mutex er låst opp av fengselsdirektøren");      puts("mutex er låst opp av fengselsdirektøren");
93    
94      puts("fengselsdirektøren signalerer livstidsfangene");      puts("fengselsdirektøren signalerer livstidsfangene");
95      pthread_cond_signal(&cond);      pthread_cond_signal(&cond);
96      puts("signal er sendt fra fengselsdirektøren");      puts("signal er sendt fra fengselsdirektøren");
97    
98      puts("fengselsdirektøren venter på å få låst mutex");      puts("fengselsdirektøren venter på å få låst mutex");
99      pthread_mutex_lock(&mutex);      pthread_mutex_lock(&mutex);
# Line 166  void visResultater(void) Line 178  void visResultater(void)
178      } // else      } // else
179    
180      // Tusle ut av rommet.      // Tusle ut av rommet.
181      printf("livstidsfange %2zu låser opp mutex\n", i + 1);      printf("livstidsfange %2zu låser opp mutex\n", i + 1);
182      pthread_mutex_unlock(&mutex);      pthread_mutex_unlock(&mutex);
183      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);
184    } // while    } // while
185  } // livstidsfange()  } // livstidsfange()
186    
187  void visResultater(void)  void visResultater(void)
188  {  {
189    size_t i;    size_t i;
190    
191    fflush(stderr);    fflush(stderr);
192    fflush(stdout);    fflush(stdout);
193    fflush(stderr);  
   fflush(stdout);  
194    puts("\nResultater:\n");    puts("\nResultater:\n");
195    
196    printf("bryter %u er ved avslutning vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");    printf("bryter %u er ved avslutning vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
197    printf("bryter %u er ved avslutning vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");    printf("bryter %u er ved avslutning vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
198    printf("livstidsfange %2zu var den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);    printf("livstidsfange %2zu var den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);
199    
200    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {
201      printf("livstidsfange %2zu: antall besøk: %u\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu: antall besøk: %u\n", i + 1, antallBesok[i]);
202    } // for    } // for
203      puts("");
204    
205      printf("antall livstidsfanger talt av den tellende livstidsfangen er %u\n", antallLivstidsfanger);
206    
207    fflush(stdout);    fflush(stdout);
208    fflush(stdout);    fflush(stdout);
209  } // visResultater()  } // visResultater()
210    
211  void signalhandler(int sig)  void signalhandler(int sig)
212  {  {
213    if (sig == SIGINT) {    if (sig == SIGINT) {
214      exit(1);      exit(1);
215    } // if    } // if
216  } // signalhandler()  } // signalhandler()
217    
218  // livstidsfanger.c  // livstidsfanger.c


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

svn@ximalas.info
ViewVC Help
Powered by ViewVC 1.3.0-dev