Advertisement
Guest User

Untitled

a guest
Jun 29th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.90 KB | None | 0 0
  1. /* Erzeuger-Verbraucher-Problem mit Ringpuffer & Semaphoren */
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/ipc.h>
  5. #include <sys/shm.h>
  6. #include <sys/sem.h>
  7. #include <unistd.h>
  8.  
  9.  
  10. #define BUFSIZE 100 /* 100 Zeichen Puffer */
  11.  
  12. char *ring; /* Zeiger auf Ringpuffer */
  13. int *in,*out; /* Zeiger auf in/out-Indizes */
  14. int semset; /* Semaphorenset-Identifier */
  15.  
  16.  
  17. void sem_init(int semnr, int value) {
  18. /* Init-Operation auf Semaphore semnr */
  19. int erg;
  20.  
  21. erg = semctl(semset, semnr, SETVAL, value);
  22. }
  23.  
  24. void sem_signal(int semnr) {
  25. /* Signal-Operation auf Semaphore semnr */
  26. struct sembuf semops;
  27. int erg;
  28.  
  29. semops.sem_num = semnr; /* Semaphorennummer */
  30. semops.sem_op = 1; /* Wert um 1 erhöhen */
  31. semops.sem_flg = 0; /* keine besonderen Flags */
  32.  
  33. erg = semop(semset, &semops, 1); /* Operation ausführen */
  34. }
  35.  
  36. void sem_wait(int semnr) {
  37. /* Wait-Operation auf Semaphore semnr im Semaphorenset semsetID */
  38. struct sembuf semops;
  39. int erg;
  40.  
  41. semops.sem_num = semnr; /* Semaphorennummer */
  42. semops.sem_op = -1; /* Versuch den Wert um 1 zu verringern */
  43. semops.sem_flg = 0; /* keine speziellen Flags */
  44.  
  45. erg = semop(semset, &semops, 1); /* Operation ausführen */
  46. }
  47.  
  48.  
  49. void write_element(char element) {
  50. sem_wait(1);
  51. while ((*in + 1) % BUFSIZE == *out); /* busy waiting */
  52. ring[*in] = element; /* Element auslesen */
  53. *in = (*in + 1) % BUFSIZE; /* in aktualisieren */
  54. sem_signal(1);
  55. }
  56.  
  57. char read_element(int semnr) {
  58. char element;
  59.  
  60. sem_wait(semnr); /* WAIT */
  61.  
  62. while (*in == *out); /* busy waiting */
  63. element = ring[*out]; /* Element auslesen */
  64. *out = (*out + 1) % BUFSIZE; /* out aktualisieren */
  65.  
  66. sem_signal(semnr); /* SIGNAL */
  67. return element;
  68. }
  69.  
  70.  
  71. void erzeuger(int nummer, int anzahl) { /* "produziert" anzahl Elemente */
  72. int i;
  73.  
  74. printf("Erzeuger %d gestartet \n", nummer);
  75. fflush(stdout);
  76.  
  77. for(i = 1; i <= anzahl; i++) { /* Elemente "produzieren" */
  78. write_element('A');
  79. printf("Erzeuger %d : %d Elemente produziert ...\n", nummer, i);
  80. fflush(stdout);
  81. }
  82. }
  83.  
  84. void verbraucher(int nr) {
  85. /* "verbraucht" moeglichst viele Elemente und zaehlt diese */
  86. int i;
  87. char c;
  88.  
  89. printf("Verbraucher %d gestartet \n", nr);
  90. fflush(stdout);
  91.  
  92. i = 0;
  93.  
  94. while (1) { /* Elemente "verbrauchen" */
  95. c = read_element(0);
  96. i++;
  97. printf("Verbraucher %d: %d Elemente konsumiert ...\n",nr,i);
  98. fflush(stdout);
  99. }
  100. }
  101.  
  102.  
  103. void main(int argc, char *argv[]) {
  104. int child; /* PID des Sohnprozesses */
  105. int shmID; /* shared memory ID */
  106.  
  107. /* shared memory anfordern */
  108. shmID = shmget(IPC_PRIVATE, BUFSIZE + 2 * sizeof(int), IPC_CREAT | 0x1ff);
  109.  
  110. /* Zeiger auf Ringpuffer initialisieren */
  111. ring = (char *)shmat(shmID, NULL, 0);
  112. in = (int *)(ring + 100); /* Pointer auf in-Index initialisieren */
  113. out = in + 1; /* Pointer auf out-Index initialisieren */
  114.  
  115. /* Sem.set mit einer Semaphore anfordern */
  116. semset = semget(IPC_PRIVATE, 1, IPC_CREAT | 0x1ff);
  117. if (semset == -1) {
  118. printf("Fehler: keine Semaphore mehr verfuegbar!\n");
  119. exit(1);
  120. }
  121.  
  122. sem_init(0,1); /* Semaphore 0 mit 1 initialisieren */
  123. sem_init(1,1);
  124. *in = 0; /* Indizes initialisieren */
  125. *out = 0;
  126.  
  127. child = fork();
  128. if (child == 0) {
  129. child = fork();
  130. if (child == 0) {
  131. erzeuger(1, 10000);
  132. } else {
  133. erzeuger(2, 10000);
  134. }
  135. } else {
  136. child = fork();
  137. if (child == 0) {
  138. verbraucher(1);
  139. } else {
  140. verbraucher(2);
  141. }
  142. }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement