Guest User

Untitled

a guest
Feb 19th, 2018
257
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. #define N_MAX       50      // Counting limit (incl).
  6. #define P_MAX       16      // Maximum process count.
  7. #define D_MAX       3       // Maximum allowed digits.
  8.  
  9. #define FD_W(p,pmax)        (((((p) + 1) * 2) + 1) % (2 * (pmax)))
  10. #define FD_R(p,pmax)        (((p) * 2) % (2 * (pmax)))
  11.  
  12. int n, p, pmax;             // Count (n), process num (p), max process (pmax).
  13. int mpid, fds[2 * P_MAX];   // Master pid (mpid), file descriptors (fds).
  14. char b[D_MAX];              // Message buffer (b).
  15.  
  16. /* Closes all file descriptors besides those specified for reading/writing. */
  17. void closeExcept (int r, int w) {
  18.     for (int i = 0; i < 2 * pmax; i++) {
  19.         if (i == r || i == w) continue;
  20.         close(fds[i]);
  21.     }
  22. }
  23.  
  24. int main (int argc, const char *argv[]) {
  25.     mpid = getpid();
  26.     pmax = atoi(argv[1]);
  27.  
  28.     // Initialize all pipes.
  29.     for (p = 0; p < pmax; p++) {
  30.         pipe(fds + 2 * p);
  31.     }
  32.  
  33.     // Create all forks with their process number.
  34.     for (p = 1; p < pmax; p++) {
  35.         if (fork() == 0) break;
  36.     }
  37.  
  38.     // Ensure master-process has (p = 0).
  39.     p = (getpid() == mpid) ? 0 : p;
  40.  
  41.     // Close all file-descriptors except those this process -
  42.     // will read and write from.
  43.     closeExcept(FD_R(p, pmax), FD_W(p, pmax));
  44.  
  45.     // If master process, kick off the ring.
  46.     if (getpid() == mpid) {
  47.         printf("PID %d: 0\n", mpid);
  48.         sprintf(b, "%d", 1);
  49.         write(fds[FD_W(p, pmax)], b, D_MAX);
  50.     }
  51.  
  52.     // All processes: (while n <= N_MX)
  53.     // 1. Poll the reading file-descriptor for a number.
  54.     // 2. Print acquired number.
  55.     // 3. Incremented and send acquired number to next process.
  56.     for (int bytes_read = 0; n <= N_MAX; ) {
  57.         if ((bytes_read = read(fds[FD_R(p, pmax)], b, D_MAX)) == D_MAX) {
  58.  
  59.             if ((n = atoi(b)) <= N_MAX) {
  60.                 printf("PID %d: %d\n", getpid(), n);
  61.             }
  62.             sprintf(b, "%d", n + 1);
  63.             write(fds[FD_W(p, pmax)], b, D_MAX);
  64.         } else {
  65.             break;
  66.         }
  67.     }
  68.     return 0;
  69. }
RAW Paste Data