int main(int argc, char *argv[]) {

  signal(SIGTERM, my_handler);
  signal(SIGINT, my_handler);

  create_if_missing(REF_FILE, S_IRUSR | S_IWUSR);

  key_t key = ftok(REF_FILE, 0);
  handle_error(key, "ftok failed", PROCESS_EXIT);

  int id = msgget(key, IPC_CREAT | MSGPERM);
  msgqid_for_cleanup = id;

  handle_error(id, "child msgget failed", PROCESS_EXIT);
  printf("id=%d key=%ld\n", id, (long) key);

  for (int i = 1; i <= N; i++) {
    /* create a child process so communication can be tested */
    int pid = fork();
    handle_error(pid, "fork failed", PROCESS_EXIT);
    if (pid == 0) {
      printf("in child pid=%d (ppid=%d)\n", getpid(), getppid());
      child(id, i);
    }
  }
  atexit(cleanup_queue);
  parent(id);
}
Exemple #2
0
int setup_shm() {
	/* set up shared Memory */
	printf("Setting up shared Memory ...");

	/* create REF File, if it not exists */
	remove(REF_FILE);
	create_if_missing(REF_FILE, S_IRUSR | S_IWUSR);

	/*create shm 'unique' key */
	key_t shm_key = ftok(REF_FILE, 1);
	if (shm_key < 0) {
		handle_error(-1, "ftok failed", NO_EXIT);
	}
	create_shm(shm_key, "create", "shmget failed", IPC_CREAT | IPC_EXCL);
	shm_id = create_shm(shm_key, "create", "shmget failed", 0);
	return 1;
}
int main(int argc, char *argv[]) {

  time_t t_start = time(NULL);

  if (is_help_requested(argc, argv)) {
    usage(argv[0], "");
  }

  if (argc > 2) {
    usage(argv[0], "too many arguments");
  }

  int retcode = 0;

  create_if_missing(REF_FILE, S_IRUSR | S_IWUSR);

  key_t shm_key = ftok(REF_FILE, 1);
  if (shm_key < 0) {
    handle_error(-1, "ftok failed", PROCESS_EXIT);
  }

  key_t sem_key = ftok(REF_FILE, 2);
  if (sem_key < 0) {
    handle_error(-1, "ftok failed", PROCESS_EXIT);
  }

  if (argc == 2 && strcmp(argv[1], "-s") == 0) {
    printf("setting up IPC\n");
    int shm_id = create_shm(shm_key, "create", "shmget failed", IPC_CREAT);
    shmid_for_cleanup = shm_id;
    int semaphore_id = create_sem(sem_key, SEM_SIZE, "create", "semget (data) failed", IPC_CREAT);
    semid_for_cleanup = semaphore_id;

    show_sem_ctl(semaphore_id, 0, "semaphore before setup");
    setup_sem(semaphore_id, "semaphore setup failed");
    show_sem_ctl(semaphore_id, 0, "semaphore after setup");
    printf("done\n");
    exit(0);
  }

  int shm_id = create_shm(shm_key, "create", "shmget failed", 0);
  shmid_for_cleanup = shm_id;
  int semaphore_id = create_sem(sem_key, SEM_SIZE, "create", "semget failed", 0);
  semid_for_cleanup = semaphore_id;

  if (argc == 2 && strcmp(argv[1], "-c") == 0) {
    printf("cleaning up IPC\n");
    cleanup();
    exit(0);
  }

  char *name = "";
  if (argc == 2) {
    name = argv[1];
  }

  struct data *shm_data = (struct data *) shmat(shm_id, NULL, 0);

  time_t total_data_semops_wait = 0;
  char buffer[BUF_SIZE];
  long *counter = shm_data->counter;

  while (TRUE) {
    ssize_t size_read = read(STDIN_FILENO, buffer, BUF_SIZE);
    if (size_read == 0) {
      /* end of file */
      break;
    }
    handle_error(size_read, "error while reading stdin", PROCESS_EXIT);
    int i;
    for (i = 0; i < size_read; i++) {
      unsigned char c = buffer[i];
      unsigned int  ck = c % SEM_SIZE;
      struct sembuf semops_write;
      semops_write.sem_num = ck;
      semops_write.sem_op  = -SEM_LIMIT;
      semops_write.sem_flg = SEM_UNDO;
      time_t t0 = time(NULL);
      // show_sem_ctl(semaphore_id, ck, "reserving write semaphore");
      retcode = semop(semaphore_id, &semops_write, 1);
      handle_error(retcode, "error while getting write-semaphore", PROCESS_EXIT);
      // show_sem_ctl(semaphore_id, ck, "write semaphore reserved");
      time_t dt = time(NULL) - t0;
      total_data_semops_wait += dt;
      counter[c]++;
      semops_write.sem_num = ck;
      semops_write.sem_op  = SEM_LIMIT;
      semops_write.sem_flg = SEM_UNDO;
      // show_sem_ctl(semaphore_id, ck, "freeing write semaphore");
      retcode = semop(semaphore_id, &semops_write, 1);
      handle_error(retcode, "error while releasing write-semaphore", PROCESS_EXIT);
      // show_sem_ctl(semaphore_id, ck, "write semaphore freed");
    }
  }

  time_t total_duration = time(NULL) - t_start;

  unsigned int i;

  char output_buffer[16384];
  char *output_ptr = output_buffer;
  int n;
  int m = 0;
  n = sprintf(output_ptr, "------------------------------------------------------------\n");
  output_ptr += n; m += n;
  n = sprintf(output_ptr, "%s: pid=%ld\n", name, (long) getpid());
  output_ptr += n; m += n;
  n = sprintf(output_ptr, "total wait for data: ~ %ld sec; total duration: ~ %ld\n", (long) total_data_semops_wait, (long) total_duration);
  output_ptr += n; m += n;
  n = sprintf(output_ptr, "------------------------------------------------------------\n");
  output_ptr += n; m += n;
  for (i = 0; i < ALPHA_SIZE; i++) {
    struct sembuf semops_read;
    unsigned int  ck = (i % SEM_SIZE);
    semops_read.sem_num = ck;
    semops_read.sem_op  = -1;
    semops_read.sem_flg = SEM_UNDO;
    retcode = semop(semaphore_id, &semops_read, 1);
    handle_error(retcode, "error while getting read-semaphore", PROCESS_EXIT);
    long *counter = shm_data->counter;
    long val = counter[i];
    semops_read.sem_op  = 1;
    retcode = semop(semaphore_id, &semops_read, 1);
    handle_error(retcode, "error while releasing read-semaphore", PROCESS_EXIT);
    if (! (i & 007)) {
      n = sprintf(output_ptr, "\n");
      output_ptr += n; m += n;
    }
    if ((i & 0177) < 32 || i == 127) {
      n = sprintf(output_ptr, "\\%03o: %10ld    ", i, val);
      output_ptr += n; m += n;
    } else {
      n = sprintf(output_ptr, "%4c: %10ld    ", (char) i, val);
      output_ptr += n; m += n;
    }
  }
  n = sprintf(output_ptr, "\n\n");
  output_ptr += n; m += n;
  n = sprintf(output_ptr, "------------------------------------------------------------\n\n");
  output_ptr += n; m += n;
  write(STDOUT_FILENO, output_buffer, (size_t) m);

  exit(0);
}
int main(int argc, char *argv[]) {
  int i;
  int retcode;

  signal(SIGTERM, my_handler);
  signal(SIGINT, my_handler);

  create_if_missing(REF_FILE, S_IRUSR | S_IWUSR);

  key_t key = ftok(REF_FILE, 0);
  handle_error(key, "ftok failed", PROCESS_EXIT);

  /* create a second process so communication can be tested */
  int pid = fork();
  handle_error(pid, "fork failed", PROCESS_EXIT);
  if (pid == 0) {
    printf("in child pid=%d (ppid=%d)\n", getpid(), getppid());
    struct msg msg;

    int id = msgget(key, IPC_CREAT | MSGPERM);
    handle_error(id, "child msgget failed", PROCESS_EXIT);

    printf("child: id=%d key=%ld\n", id, (long) key);

    //show_msg_ctl(id, "child");

    for (i = 0; i < 100; i++) {
      msg.data.c = 'C';
      msg.data.x = i;
      msg.data.y = i*i;
      msg.type = i + 101;
      retcode = msgsnd(id, &msg, SIZE, 0);
      handle_error(retcode, "msgsnd failed", PROCESS_EXIT);
      struct timespec duration;
      duration.tv_sec = (time_t) 0;
      duration.tv_nsec = 100000000L;
      nanosleep(&duration, NULL);
    }
    msg.data.c = 'Q';
    msg.type   = 100;
    msgsnd(id, &msg, SIZE, 0);
    printf("terminating child\n");
    exit(0);

  } else {
    atexit(cleanup_queue);
    printf("in parent pod=%d (child_pid=%d)\n", getpid(), pid);
    sleep(1);
    printf("reading in parent\n");

    struct msg msg;
    int id = msgget(key, IPC_CREAT | MSGPERM);
    msgqid_for_cleanup = id;
    handle_error(id, "parent msgget failed", PROCESS_EXIT);

    printf("parent: id=%d key=%ld\n", id, (long) key);

    //show_msg_ctl(id, "child");

    for (i = 150; i >= 50; i--) {
      retcode = msgrcv(id, &msg, SIZE, -i, 0);
      handle_error(retcode, "parent msgrcv failed", PROCESS_EXIT);
      char c = msg.data.c;
      long t = msg.type;
      if (c == 'Q') {
        printf("i=%3d t=%3ld c=Q\n", i, t);
        break;
      }
      int x = msg.data.x;
      int y = msg.data.y;
      printf("i=%3d t=%3ld: %4d^2 = %6d\n", i, t, x, y);
    }
    printf("terminating parent\n");
    cleanup_queue();
    exit(0);
  }
}
int main(int argc, char *argv[]) {

  time_t t0 = time(NULL);

  if (argc > 2) {
    printf("Usage\n\n");
    printf("%s -c\ncleanup ipc\n\n", argv[0]);
    printf("%s -s\nsetup ipc\n\n", argv[0]);
    printf("%s < inputfile\ncout file, show accumulated output\n\n", argv[0]);
    printf("%s name < inputfile\ncout file, show output with name\n\n", argv[0]);
    exit(1);
  }

  int retcode = 0;


  create_if_missing(REF_FILE, S_IRUSR | S_IWUSR);

  key_t shm_key = ftok(REF_FILE, 1);
  if (shm_key < 0) {
    handle_error(-1, "ftok failed", PROCESS_EXIT);
  }

  if (argc == 2 && strcmp(argv[1], "-s") == 0) {
    printf("setting up IPC\n");
    create_shm(shm_key, "create", "shmget failed", IPC_CREAT | IPC_EXCL);
    create_sem(1, "sem_open failed", O_CREAT | O_EXCL);
    printf("done\n");
    exit(0);
  }

  int shm_id = create_shm(shm_key, "create", "shmget failed", 0);

  sem_t *sem_ptr = create_sem(1, "semget failed", 0);

  if (argc == 2 && strcmp(argv[1], "-c") == 0) {
    printf("cleaning up IPC\n");
    cleanup(shm_id, sem_ptr);
    exit(0);
  }

  char *name = "";
  if (argc == 2) {
    name = argv[1];
  }

  struct data *shm_data = (struct data *) shmat(shm_id, NULL, 0);

  char buffer[BUF_SIZE];
  struct data local_data;
  long *counter = local_data.counter;
  for (int i = 0; i < ALPHA_SIZE; i++) {
    counter[i] = 0L;
  }

  while (TRUE) {
    ssize_t size_read = read(STDIN_FILENO, buffer, BUF_SIZE);
    if (size_read == 0) {
      /* end of file */
      break;
    }
    handle_error(size_read, "error while reading stdin", PROCESS_EXIT);
    int i;
    for (i = 0; i < size_read; i++) {
      unsigned char c = buffer[i];
      counter[c]++;
    }
  }

  unsigned int i;

  time_t t1 = time(NULL);
  retcode = sem_wait(sem_ptr);
  handle_error(retcode, "error while getting semaphore", PROCESS_EXIT);
  time_t dt = time(NULL) - t1;

  for (int i = 0; i < ALPHA_SIZE; i++) {
    long *tcounter = shm_data->counter;
    long *scounter = local_data.counter;
    tcounter[i] += scounter[i];
  }

  time_t total = time(NULL) - t0;

  printf("------------------------------------------------------------\n");
  printf("%s: pid=%ld\n", name, (long) getpid());
  printf("total time for calculation: ~ %ld sec; total wait for semaphore: ~ %ld sec\n", (long) total, (long) dt);
  printf("------------------------------------------------------------\n");
  for (i = 0; i < ALPHA_SIZE; i++) {
    long *counter = shm_data->counter;
    long val = counter[i];

    if (! (i & 007)) {
      printf("\n");
      fflush(stdout);
    }
    if ((i & 0177) < 32 || i == 127) {
      printf("\\%03o: %10ld    ", i, val);
    } else {
      printf("%4c: %10ld    ", (char) i, val);
    }
  }
  printf("\n\n");
  printf("------------------------------------------------------------\n\n");
  fflush(stdout);

  retcode = sem_post(sem_ptr);
  handle_error(retcode, "error while releasing semaphore", PROCESS_EXIT);

  retcode = sem_close(sem_ptr);
  handle_error(retcode, "error while closing semaphore", PROCESS_EXIT);

  retcode = shmdt(shm_data);
  handle_error(retcode, "error while detaching shared memory", PROCESS_EXIT);
  /* cleanup(); */
  printf("done\n");
  exit(0);
}