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); }
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); }