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

Diff of /trunk/livstidsfanger.c

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

Revision 5 by trond, 2014-11-07T08:04:18Z Revision 7 by trond, 2014-11-07T08:56:07Z
# 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-1995). -*- coding: utf-8 -*-
2  // Løsning laget 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  #include <errno.h>  #include <errno.h>
7  #include <pthread.h>  #include <pthread.h>
8  #include <signal.h>  #include <signal.h>
9  #include <stdbool.h>  #include <stdbool.h>
10  #include <stdio.h>  #include <stdio.h>
11  #include <stdlib.h>  #include <stdlib.h>
12  #include <string.h>  #include <string.h>
13  #include <unistd.h>  #include <unistd.h>
14    
15  #if __STDC_VERSION__ >= 201112L  #if __STDC_VERSION__ >= 201112L
16  #include <stdnoreturn.h>  #include <stdnoreturn.h>
17  #else  #else
# Line 37  noreturn int main(int argc, char **argv) Line 37  noreturn int main(int argc, char **argv)
37  {  {
38    size_t i;    size_t i;
39    pthread_t tid = pthread_self();    pthread_t tid = pthread_self();
40    
41    atexit(visResultater);    atexit(visResultater);
42    signal(SIGINT, signalhandler);    signal(SIGINT, signalhandler);
43    
44    srandomdev();    srandomdev();
45    
46    memset((void *)&antallBesok, 0, sizeof(antallBesok));    memset((void *)&antallBesok, 0, sizeof(antallBesok));
47    brytere[0] = random() & 1;    brytere[0] = random() & 1;
48    brytere[1] = random() & 1;    brytere[1] = random() & 1;
49    
50    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;
51    
52      printf("bryter %u er i utgangspunktet vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
53      printf("bryter %u er i utgangspunktet vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
54      printf("livstidsfange %zu er utpekt som den tellende livstidsfange\n\n", tellendeLivstidsfange + 1);
55    
56    puts("maintråden venter på å få låst mutex");    puts("maintråden venter på å få låst mutex");
57    pthread_mutex_lock(&mutex);    pthread_mutex_lock(&mutex);
58    puts("mutex er låst av maintråden");    puts("mutex er låst av maintråden");
59    
60    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {
61      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);
62    
63      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {
64        fprintf(stderr,        fprintf(stderr,
65                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",
66                argv[0], i, strerror(errno), errno);                argv[0], i, strerror(errno), errno);
67        exit(1);        exit(1);
68      } // if      } // if
69    } // for    } // for
70    
# Line 95  noreturn void *livstidsfange(void *arg) Line 99  noreturn void *livstidsfange(void *arg)
99      antallLivstidsfanger++;      antallLivstidsfanger++;
100    } // if    } // if
101    
102    while (1) {    while (1) {
103      // Vente på tur.      // Vente på tur.
104      printf("livstidsfange %2zu venter på å få låst mutex\n", i + 1);      printf("livstidsfange %2zu venter på å få låst mutex\n", i + 1);
105      pthread_mutex_lock(&mutex);      pthread_mutex_lock(&mutex);
106      printf("livstidsfange %2zu har låst mutex\n", i + 1);      printf("livstidsfange %2zu har låst mutex\n", i + 1);
107    
108      printf("livstidsfange %2zu venter på signal fra fengselsdirektøren\n", i + 1);      printf("livstidsfange %2zu venter på signal fra fengselsdirektøren\n", i + 1);
109      pthread_cond_wait(&cond, &mutex);      pthread_cond_wait(&cond, &mutex);
110      printf("livstidsfange %2zu har fått signal fra fengselsdirektøren og har låst mutex\n", i + 1);      printf("livstidsfange %2zu har fått signal fra fengselsdirektøren og har låst mutex\n", i + 1);
111    
112      // Utføre selve simuleringen ved å sjekke brytere, m.m.      // Utføre selve simuleringen ved å sjekke brytere, m.m.
113      antallBesok[i]++;      antallBesok[i]++;
114      printf("livstidsfange %2zu har besøkt rommet %u ganger\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu har besøkt rommet %u gang%s\n", i + 1, antallBesok[i], antallBesok[i] == 1 ? "" : "er");
115    
116      if (i == tellendeLivstidsfange) {      if (i == tellendeLivstidsfange) {
117        if (brytere[0] == false) {        if (brytere[0] == false) {
118          printf("livstidsfange %2zu ser at bryter 1 er nede og vipper opp bryter 1\n", i + 1);          printf("livstidsfange %2zu ser at bryter 1 er nede og vipper opp bryter 1\n", i + 1);
119          brytere[0] = true;          brytere[0] = true;
120        } // if        } // if
121        else {        else {
122          brytere[0] = !brytere[0];          brytere[0] = !brytere[0];
123          printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == 1U ? "opp" : "ned");          printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == 1U ? "opp" : "ned");
124    
125          if (forrigeGangErGyldig == true && forrigeGang == false) {          if (forrigeGangErGyldig == true && forrigeGang == false) {
126            antallLivstidsfanger++;            antallLivstidsfanger++;
127            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);
128    
129            if (antallLivstidsfanger == ANTALL_LIVSTIDSFANGER) {            if (antallLivstidsfanger == ANTALL_LIVSTIDSFANGER) {
# Line 159  void visResultater(void) Line 163  void visResultater(void)
163      // Tusle ut av rommet.      // Tusle ut av rommet.
164      printf("livstidsfange %2zu låser opp mutex\n", i + 1);      printf("livstidsfange %2zu låser opp mutex\n", i + 1);
165      pthread_mutex_unlock(&mutex);      pthread_mutex_unlock(&mutex);
166      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);
167    } // while    } // while
168  } // livstidsfange()  } // livstidsfange()
169    
170  void visResultater(void)  void visResultater(void)
171  {  {
172    size_t i;    size_t i;
173    
174    fflush(stderr);    fflush(stderr);
175    fflush(stdout);    fflush(stdout);
176    fflush(stderr);    fflush(stderr);
177    fflush(stdout);    fflush(stdout);
178    puts("");    puts("\nResultater:\n");
179    
180    printf("livstidsfange %2zu er den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);    printf("bryter %u er ved avslutning vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
181      printf("bryter %u er ved avslutning vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
182      printf("livstidsfange %2zu var den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);
183    
184    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {
185      printf("livstidsfange %2zu: antall besøk = %u\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu: antall besøk: %u\n", i + 1, antallBesok[i]);
186    } // for    } // for
187    
188    fflush(stdout);    fflush(stdout);
189    fflush(stdout);    fflush(stdout);
190  } // visResultater()  } // visResultater()
191    
192  void signalhandler(int sig)  void signalhandler(int sig)
193  {  {
194    if (sig == SIGINT) {    if (sig == SIGINT) {
195      exit(1);      exit(1);
196    } // if    } // if
197  } // signalhandler()  } // signalhandler()
198    
199  // 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