#include #include #include #include #include #include #include #include #include #include #include /* ***esercizio B4 'due processi' *** Due processi: A (parent) e B (child), condividono un file aperto in modalità scrittura (e quindi anche l'offset del file). il processo A fa l'append di una riga di testo al file; dorme un secondo; comunica al processo B di continuare. Il processo A aspetta. il processo B, a sua volta, fa l'append di una riga di testo allo stesso file; dorme un secondo; comunica al processo A di continuare. Il processo B aspetta. Quando il processo A ha scritto la centesima riga ,manda un segnale di terminazione al processo B, aspetta che B termini e poi termina anche A. */ #define N 100 pid_t parent_pid; pid_t child_pid; void signal_handler(int signum) { printf("[signal_handler] %s\n", getpid() == parent_pid ? "parent process" : "child process"); } int main() { int fd; char * filename = "prova.txt"; char buffer[256]; int res; struct timespec ts = { 0, 10000000 }; // per i test: 10 ms fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); if (fd == -1) { perror("open"); exit(1); } if (signal(SIGUSR1, signal_handler) == SIG_ERR) { perror("signal"); exit(1); } parent_pid = getpid(); child_pid = fork(); if (child_pid == -1) { perror("fork"); exit(1); } if (child_pid == 0) { // child process for (int i = 0;; i++) { // ciclo senza fine printf("[child] before pause\n"); pause(); printf("[child] after pause\n"); sprintf(buffer, "[child] data=%d\n", i); printf("[child] before write\n"); res = write(fd, buffer, strlen(buffer)); if (res == -1) { perror("write"); exit(1); } printf(buffer); printf("[child] before nanosleep\n"); res = nanosleep(&ts, NULL); if (res == -1 && errno == EINTR) { printf("!!! nanosleep interrupted by signal\n"); // non deve accadere... } printf("[child] before kill\n"); if (kill(child_pid, SIGUSR1) == -1) { perror("kill"); exit(1); } } // processo figlio non passerà mai di qua } else { // parent process for (int i = 0; i < N; i++) { sprintf(buffer, "[parent] data=%d\n", i); printf("[parent] before write\n"); res = write(fd, buffer, strlen(buffer)); if (res == -1) { perror("write"); exit(1); } printf(buffer); printf("[parent] before nanosleep\n"); res = nanosleep(&ts, NULL); if (res == -1 && errno == EINTR) { printf("!!! nanosleep interrupted by signal\n"); // non deve accadere... } printf("[parent] before kill\n"); if (kill(child_pid, SIGUSR1) == -1) { perror("kill"); exit(1); } printf("[parent] before pause\n"); pause(); printf("[parent] after pause\n"); } // questo fa terminare il processo figlio if (kill(child_pid, SIGINT) == -1) { perror("kill"); exit(1); } if (wait(NULL) == -1) { perror("wait"); } } printf("[parent] bye\n"); return 0; }