int main() { char* argumentos[MAX_ARGS + 1]; char buffer[BUFFER_SIZE]; list = lst_new(); int pid; pthread_t tid; pthread_mutex_init(&mutex, NULL); // Criar tarefa para monitorizar os filhos if(pthread_create(&tid, 0, tarefa_monitor,NULL) != 0) { perror("Erro no pthread_create: "); exit(EXIT_FAILURE); } while(1){ if(readLineArguments(argumentos,MAX_ARGS,buffer,BUFFER_SIZE) <= 0){ continue; } if(strcmp(argumentos[0],"exit")==0) { // exit - esperar pela tarefa monitora e imprimir as informacoes dos filhos pthread_mutex_lock(&mutex); exit_ative = true; pthread_mutex_unlock(&mutex); pthread_join(tid,NULL); lst_print(list); pthread_mutex_destroy(&mutex); exit(EXIT_SUCCESS); } else { pid = fork(); time_t starttime = time(NULL); if (pid < 0) { perror("Erro no fork"); continue; } if (pid == 0) { // Codigo do filho execv(argumentos[0], argumentos); perror("Erro no execv:"); exit(EXIT_FAILURE); } // Codigo do pai pthread_mutex_lock(&mutex); nfilhos++; insert_new_process(list,pid,starttime); pthread_mutex_unlock(&mutex); } } return 0; }
int main(int argc, char **argv){ char buffer[BUFFER_SIZE]; int numArgs; char *arg_vector[VECTOR_SIZE]; time_t starttime; int child_pid; pthread_t monitor_thread; pthread_t writer_thread; lst = lst_new(); writing_queue = new_queue(); /* Initialize synchronization objects */ pthread_mutex_init_(&mutex, NULL); pthread_cond_init_(&write_cond, 0); pthread_cond_init_(&max_par, NULL); pthread_cond_init_(&new_child, NULL); if ((log_fd = fopen("./log.txt", "a+")) == NULL){ perror("[ERROR] opening log file"); exit(EXIT_FAILURE); } read_log(); /* assign total time and iteration values for this execution */ pthread_create_(&monitor_thread, NULL, (void *)&monitor, NULL); /* Create Monitor Thread */ pthread_create_(&writer_thread, NULL, (void *)&writer, NULL); /* Create Writer Thread */ while (1) { numArgs = readLineArguments(arg_vector, VECTOR_SIZE, buffer, BUFFER_SIZE); if (numArgs <= 0)continue; if (strcmp(arg_vector[0], EXIT_COMMAND) == 0 ) { /* signal exit command */ exit_command = 1; /* wait for monitor thread to end */ pthread_cond_signal_(&new_child); /* must signal to catch exit flag */ pthread_join_(monitor_thread, NULL); pthread_join_(writer_thread, NULL); /* print all the elements in the list */ lst_print(lst); /* terminate sync objects */ pthread_mutex_destroy_(&mutex); pthread_cond_destroy_(&write_cond); pthread_cond_destroy_(&max_par); pthread_cond_destroy_(&new_child); fclose(log_fd); lst_destroy(lst); exit(EXIT_SUCCESS); } /* while there are child process slots available launch new child process, * else wait here */ pthread_mutex_lock_(&mutex); while (child_count >= MAXPAR) pthread_cond_wait_(&max_par, &mutex); pthread_mutex_unlock_(&mutex); child_pid = fork(); if (child_pid < 0){ /* test for error in fork */ perror("[ERROR] forking process"); continue; } if (child_pid == 0){ /* execute on child */ if (execv(arg_vector[0], arg_vector) == -1) { perror("[ERROR] executing program."); exit(EXIT_FAILURE); } } else { /* execute on parent */ /* Main thread * * Child processes are inserted into the process list saving their pid * and their start time. * Child counter is incremented. * The condition variable waiting for a new child process is signaled. */ time(&starttime); /* get start time of child process */ pthread_mutex_lock_(&mutex); insert_new_process(lst, child_pid, starttime); child_count++; pthread_cond_signal_(&new_child); pthread_mutex_unlock_(&mutex); } } }
/*=================================================== = Programa principal = ===================================================*/ int main() { char* argumentos[MAX_ARGS]; // Argumentos dos executáveis char buffer[BUFFER_SIZE]; // Buffer que guarda os dados da leitura do pipe int input; // Descritor de ficheiro para o pipe que recebe input dos terminais /** * Inicializar as variáveis e estruturas da par-shell */ initialize_variables(); /** * Atualizar as informações do log da par-shell */ update_log_values(); /** * Catch do signal ctrl+c */ if(signal(SIGINT, sig_handler) == SIG_ERR){ perror("Erro no signal: "); } while(1){ /** * Abrir o pipe que recebe input dos terminais */ if((inputdesc = open(inputpipe,O_RDONLY)) < 0){ perror("Erro no open do pipe: "); exit(EXIT_FAILURE); } /** * Ler informações do pipe */ if((input = read(inputdesc,buffer,BUFFER_SIZE)) <= 0){ // Fechar o pipe apos a leitura close(inputdesc); // Não lê nada mas tambem não dá erro, continua o ciclo (e.g press enter) if(input == 0){ continue; } perror("Erro no read do input"); } else{ buffer[input] = '\0'; if(strcmp(buffer,"exit-global") == 0) { /** * Sair da par-shell */ exit_par_shell(); } if (sscanf(buffer, "/tmp/terminal-%d", &pidterminal) > 0) { /** * Registar um terminal especifico e o seu pipe */ printf("Terminal %d criado\n",pidterminal); if(fflush(stdout) < 0) perror("Erro no fflush de escrita no par-shell na criação de terminal: "); // Inserir pid do terminal na lista de terminais insert_new_terminal(lista_terminais,pidterminal); continue; } if(sscanf(buffer,"stats %d",&pidterminal) > 0){ /** * Enviar o número de processos filhos em execução e * o tempo total de execução da par-shell para o terminal */ // Construir strings de output e do nome do pipe do terminal sprintf(output,"Número de filhos em execução: %d \nTempo total: %g",nfilhos,tempo_total_execucao); sprintf(terminalpipe,"/tmp/terminal-%d",pidterminal); // Abrir o pipe do terminal para escrita if((fd_write = open(terminalpipe, O_WRONLY)) < 0){ perror("Erro no open do stats da par-shell: "); exit(EXIT_FAILURE); } // Escrever no pipe do terminal if(write(fd_write,output,strlen(output)) < 0){ perror("Erro no write do stats da par-shell: "); } // Fechar o pipe do terminal if(close(fd_write) < 0){ perror("Erro no close do stats da par-shell: "); } strcpy(output,"\0"); continue; } else { int i; // Inteiro temporário usado no ciclo de processamento dos argumentos int pid; // Pid do processo filho criado com fork /** * Processar todos os argumentos que poderá receber */ argumentos[0] = strtok(buffer," "); for(i = 1; i < MAX_ARGS; i++){ argumentos[i] = strtok(NULL," "); } /** * Confirmar se podem ser criados filhos */ mutex_lock(); while (! (nfilhos < MAXPAR)) if(pthread_cond_wait(&podeCriarFilhos,&mutex) != 0){ perror("Erro no pthread_cond_wait na par-shell: "); } mutex_unlock(); /** * Criar processo filho usando fork */ pid = fork(); // Registar tempo de inicio do processo filho time_t starttime = time(NULL); if (pid < 0) { perror("Erro no fork: "); continue; } /** * Código do processo filho */ if (pid == 0) { // Redirecionar o output do processo filho redirect_stdout(); // Evitar que o ctrl+c se propague para o processo filho -> signal é ignorado signal(SIGINT,SIG_IGN); // Trocar código do processo filho pelo do executável if(execv(argumentos[0], argumentos) < 0){ perror("Erro no execv:"); exit(EXIT_FAILURE); } } /** * Código do processo pai */ mutex_lock(); nfilhos++; if(pthread_cond_signal(&podeMonitorizar) != 0){ perror("Erro no pthread_cond_signal na par-shell: "); } insert_new_process(list,pid,starttime); mutex_unlock(); } } } return 0; }
/*//////////////////////////////////////////// /////////////// MAIN FUNCTION //////////////// ////////////////////////////////////////////*/ int main() { char* arg[7]; char buffer[100], filename[100], fnamePipeStats[100]; int vectorSize = 7, pid, numargs, fd, fDescPIPE, fDescPIPE_S; pthread_t waitChild; pid_t pidChild; terminalLst* terminals = new_terminal_lst(); l = lst_new(); if (pthread_mutex_lock(&mutex) != 0) { perror(error_mutex_lock); } if (pthread_mutex_unlock(&mutex) != 0) { perror(error_mutex_unlock); } if (pthread_mutex_init(&mutex, NULL) != 0){ perror(error_mutex); } if (pthread_cond_init(&can_wait, NULL) != 0) { perror(error_cond_init_wait); } if (pthread_cond_init(&can_execute, NULL) != 0) { perror(error_cond_init_execute); } if (pthread_create(&waitChild, NULL, waitThread, NULL) != 0) { perror(error_thread_create); exit(EXIT_FAILURE); } if (signal(SIGINT, CTRLC) == SIG_ERR) { perror(error_signal); } unlink(PIPE); /*-------------------------------------------------*/ if (mkfifo(PIPE, 0777) != 0) { perror(error_mkfifo); exit(EXIT_FAILURE); } if ((fDescPIPE = open(PIPE, O_RDONLY)) == -1) { perror(error_pipe_open); exit(EXIT_FAILURE); } close(0); dup2(fDescPIPE, 0); while (1) { numargs = readLineArguments(arg, vectorSize, buffer, 100); if(flag_signal) break; if (numargs <= 1) { continue; } if (pthread_mutex_lock(&mutex) != 0) { perror(error_mutex_lock); } while (numChildren == MAXPAR) { if (pthread_cond_wait(&can_execute, &mutex) != 0) { perror(error_cond_wait); } } if (pthread_mutex_unlock(&mutex) != 0) { perror(error_mutex_unlock); } else if (strcmp(arg[0], EXIT) != 0) { if (strcmp(arg[0], starter) == 0) { int pid_terminal = atoi(arg[1]); insert_terminal(terminals, pid_terminal); continue; } if (strcmp(arg[0], stats) == 0) { /*tratar o PID e meter na lista*/ sprintf(fnamePipeStats, "%s-%s", PIPE_S, arg[1]); while((fDescPIPE_S = open(fnamePipeStats, O_WRONLY)) < 0); if(fDescPIPE < 0) { perror(error_pipe_open); exit(EXIT_FAILURE); } if (pthread_mutex_lock(&mutex) != 0) { perror(error_mutex_lock); } sprintf (buffer, "Number of active children: %d\nTotal execution time to the moment: %d", numChildren, timeTotal); write(fDescPIPE_S, buffer, strlen(buffer)); if (pthread_mutex_unlock(&mutex) != 0) { perror(error_mutex_unlock); } close(fDescPIPE_S); continue; } if (strcmp(arg[0], EXITGLOBAL) == 0) { /* SONFOILULDNILDEFNC*/ printf("1\n"); CTRLC(SIGINT); } else { pid = fork(); if (pid < 0) { perror(error_fork); } if (pthread_mutex_lock(&mutex) != 0) { perror(error_mutex_lock); } insert_new_process(l, pid, time(NULL)); numChildren++; if (pthread_cond_signal(&can_wait) != 0) { perror(error_cond_wait); } if (pthread_mutex_unlock(&mutex) != 0) { perror(error_mutex_unlock); } if (pid == 0) { pidChild = getpid(); sprintf(filename, "par-shell-%d.txt", pidChild); fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); close(1); dup(fd); close(fd); if (execv(arg[0], arg) < 0) { perror(error_execv); exit(EXIT_FAILURE); } } else { sprintf(filename, "par-shell-%d.txt", pid); } } } else { break; } } isExit = true; if (pthread_cond_signal(&can_wait) != 0) { perror(error_cond_wait); } if (pthread_mutex_unlock(&mutex) != 0) { perror(error_mutex_unlock); } if (pthread_join(waitChild, NULL) != 0) { perror(error_thread_join); } lst_print(l); lst_destroy(l); while(remove_terminal(terminals)!= -1){ } if (pthread_cond_destroy(&can_wait) != 0) { perror(error_cond_destroy_wait); } if (pthread_cond_destroy(&can_execute) != 0) { perror(error_cond_destroy_execute); } exit(EXIT_SUCCESS); return 0; }
int main(int argc, char **argv) { pid_t child_pid; /* child process id */ pthread_t monitor_thread; /* monitor thread */ char *args[CMD_ARGS_MAX+1], buffer_cmd[LINE_COMMAND_MAX]; /* cmd related */ char buffer_log[LINE_LOGFILE_MAX]; /* log related */ if((g_lst_children = lst_new()) == NULL) { if(fprintf(stderr, "lst_new: couldn't create list\n") < 0) handle_error("fprintf"); exit(EXIT_FAILURE); } g_log_file = f_open(PATH_LOGFILE_STR, "a+"); while(!feof(g_log_file)) { f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* NULL or iteracao # */ if(feof(g_log_file)) break; if(sscanf(buffer_log, "%*s %d", &g_iterations) != 1) handle_error("sscanf"); f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* PID: # time: # s */ f_gets(buffer_log, LINE_LOGFILE_MAX, g_log_file); /* total time: # s */ if(sscanf(buffer_log, "%*[^0-9] %d", &g_total_time) != 1) handle_error("sscanf"); } ++g_iterations; cond_init(&g_child_cv); cond_init(&g_monitoring_cv); mutex_init(&g_mutex); pcreate(&monitor_thread, process_monitor, NULL); while(true) { int numargs = readLineArguments(args, CMD_ARGS_MAX + 1, buffer_cmd, LINE_COMMAND_MAX); if(args[0] == NULL) continue; if(numargs < 0 || (numargs > 0 && !strcmp(args[0], COMMAND_EXIT_STR))) { mutex_lock(&g_mutex); g_monitoring = false; cond_signal(&g_monitoring_cv); mutex_unlock(&g_mutex); pjoin(monitor_thread); lst_print(g_lst_children); destroySharedResources(); f_close(g_log_file); return EXIT_SUCCESS; } else { FILE *fp; /* To check file existance */ if ((fp = fopen(args[0], "r")) == NULL) perror(args[0]); else { f_close(fp); mutex_lock(&g_mutex); while(g_num_children == MAXPAR) cond_wait(&g_child_cv, &g_mutex); mutex_unlock(&g_mutex); if((child_pid = fork()) < 0) perror("fork"); else if(child_pid == 0) { execv(args[0],args); destroySharedResources(); handle_error("execv"); } else { mutex_lock(&g_mutex); if(insert_new_process(g_lst_children, child_pid, time(NULL)) != 0) { fprintf(stderr, "insert_new_process: failed to insert new process\n"); exit(EXIT_FAILURE); } ++g_num_children; cond_signal(&g_monitoring_cv); mutex_unlock(&g_mutex); } } } } }